diff --git a/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp b/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp index 581a7505..74d5f049 100644 --- a/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp +++ b/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp @@ -56,6 +56,7 @@ namespace DanBias { WindowShell::CreateConsoleWindow(); + //if(! m_data->window->CreateWin(WindowShell::WINDOW_INIT_DESC(L"Window", cPOINT(1600, 900), cPOINT()))) if(! m_data->window->CreateWin(WindowShell::WINDOW_INIT_DESC())) return DanBiasClientReturn_Error; @@ -114,6 +115,10 @@ namespace DanBias { if(Oyster::Graphics::API::Init(m_data->window->GetHWND(), false, false, Oyster::Math::Float2( 1024, 768)) != Oyster::Graphics::API::Sucsess) return E_FAIL; + Oyster::Graphics::API::Option p; + p.modelPath = L"..\\Content\\Models\\"; + p.texturePath = L"..\\Content\\Textures\\"; + Oyster::Graphics::API::SetOptions(p); return S_OK; } @@ -147,6 +152,7 @@ namespace DanBias if(state != Client::GameClientState::ClientState_Same) { + bool stateVal = false; m_data->recieverObj->gameClientState->Release(); delete m_data->recieverObj->gameClientState; m_data->recieverObj->gameClientState = NULL; @@ -155,23 +161,27 @@ namespace DanBias { case Client::GameClientState::ClientState_LobbyCreated: m_data->serverOwner = true; + stateVal = true; case Client::GameClientState::ClientState_Lobby: m_data->recieverObj->gameClientState = new Client::LobbyState(); + stateVal = true; break; case Client::GameClientState::ClientState_Game: - if(m_data->serverOwner) - DanBias::GameServerAPI::GameStart(); - m_data->recieverObj->gameClientState = new Client::GameState(); - if(m_data->serverOwner) - ((Client::GameState*)m_data->recieverObj->gameClientState)->setClientId(0); - else - ((Client::GameState*)m_data->recieverObj->gameClientState)->setClientId(1); + break; default: return E_FAIL; break; } - m_data->recieverObj->gameClientState->Init(m_data->recieverObj); // send game client + + if(stateVal) + { + m_data->recieverObj->gameClientState->Init(m_data->recieverObj); // send game client + } + else + { + + } } return S_OK; @@ -179,15 +189,7 @@ namespace DanBias HRESULT DanBiasGame::Render(float deltaTime) { - int isPressed = 0; - if(m_data->inputObj->IsKeyPressed(DIK_A)) - { - isPressed = 1; - } - wchar_t title[255]; - swprintf(title, sizeof(title), L"| Pressing A: %d | \n", (int)(isPressed)); - SetWindowText(m_data->window->GetHWND(), title); m_data->recieverObj->gameClientState->Render(); @@ -202,9 +204,11 @@ namespace DanBias delete m_data->recieverObj; delete m_data->inputObj; delete m_data; - Oyster::Graphics::API::Clean(); + + GameServerAPI::ServerStop(); + return S_OK; } diff --git a/Code/Game/DanBiasGame/GameClientRecieverFunc.h b/Code/Game/DanBiasGame/GameClientRecieverFunc.h index 6d4a2fda..15b0cdab 100644 --- a/Code/Game/DanBiasGame/GameClientRecieverFunc.h +++ b/Code/Game/DanBiasGame/GameClientRecieverFunc.h @@ -4,6 +4,8 @@ //WTF!? No headers included??? #include "../DanBiasGame/Include/DanBiasGame.h" #include "../GameProtocols/GeneralProtocols.h" +#include "..\GameProtocols\Protocols.h" +#include namespace DanBias { @@ -14,9 +16,15 @@ namespace DanBias // receiver function for server messages // parsing protocols and sending it to the gameState - void NetworkCallback(Oyster::Network::CustomNetProtocol& p) override + //void NetworkCallback(Oyster::Network::CustomNetProtocol& p) override + void GameRecieverObject::DataRecieved(Oyster::Network::NetEvent e) override { + Oyster::Network::CustomNetProtocol p = e.args.data.protocol; int pType = p[0].value.netInt; + + //printf("Message(%i) arrived at client(%i)\n", pType, this->GetID()); + + switch (pType) { case protocol_General_Status: @@ -60,20 +68,20 @@ namespace DanBias case protocol_Gameplay_ObjectCreate: { - Client::GameClientState::NewObj* protocolData = new Client::GameClientState::NewObj; - protocolData->object_ID = p[1].value.netInt; - protocolData->path = p[2].value.netCharPtr; + Client::GameClientState::NewObj protocolData;// = new Client::GameClientState::NewObj; + protocolData.object_ID = p[1].value.netInt; + protocolData.path = p[2].value.netCharPtr; for(int i = 0; i< 16; i++) { - protocolData->worldPos[i] = p[i+3].value.netFloat; + protocolData.worldPos[i] = p[i+3].value.netFloat; } if(dynamic_cast(gameClientState)) - ((Client::GameState*)gameClientState)->Protocol(protocolData); + ((Client::GameState*)gameClientState)->Protocol(&protocolData); - delete p[2].value.netCharPtr; //delete char array - delete protocolData; - protocolData = NULL; + //delete p[2].value.netCharPtr; //delete char array + //delete protocolData; + //protocolData = NULL; } break; case protocol_Gameplay_ObjectDisabled: @@ -102,16 +110,42 @@ namespace DanBias ((Client::GameState*)gameClientState)->Protocol(&protocolData); } break; - case protocol_Lobby_Start: + case protocol_Lobby_Create: { - /* if(dynamic_cast(gameClientState)) { + GameLogic::Protocol_LobbyCreateGame tp(); + int id = p.Get(1).value.netInt; + std::string name = p.Get(19).value.netCharPtr; + Oyster::Math::Float4x4 w; + for(int i = 0; i< 16; i++) + { + w[i] = p[i+2].value.netFloat; + } + gameClientState->Release(); delete gameClientState; + gameClientState = new Client::GameState(); - gameClientState->Init(m_data->recieverObj); - }*/ + gameClientState->Init(this); + std::wstring temp; + Utility::String::StringToWstring(name, temp); + ((Client::GameState*)gameClientState)->InitiatePlayer(id, temp, w); + + //Do some wait state? + } + } + break; + case protocol_Lobby_Start: + { + if(dynamic_cast(gameClientState)) + { + //Game state should start in n seconds + GameLogic::Protocol_LobbyStartGame p(p); + p.seconds; + + //Sleep((int)(p.seconds * 1000)); + } } break; diff --git a/Code/Game/DanBiasGame/GameClientState/GameState.cpp b/Code/Game/DanBiasGame/GameClientState/GameState.cpp index fb4b8479..335162ad 100644 --- a/Code/Game/DanBiasGame/GameClientState/GameState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/GameState.cpp @@ -15,7 +15,6 @@ struct GameState::myData Oyster::Math3D::Float4x4 view; Oyster::Math3D::Float4x4 proj; std::vector object; - int modelCount; Oyster::Network::NetworkClient* nwClient; gameStateState state; @@ -33,7 +32,8 @@ GameState::GameState(void) GameState::~GameState(void) { - + delete this->camera; + delete this->privData; } bool GameState::Init(Oyster::Network::NetworkClient* nwClient) { @@ -44,6 +44,10 @@ bool GameState::Init(Oyster::Network::NetworkClient* nwClient) privData->nwClient = nwClient; privData->state = LoadGame(); pitch = 0; + + //tELL SERver ready + nwClient->Send(GameLogic::Protocol_General_Status(GameLogic::Protocol_General_Status::States_ready)); + return true; } GameState::gameStateState GameState::LoadGame() @@ -84,11 +88,10 @@ bool GameState::LoadModels(std::wstring mapFile) // open file // read file // init models - int nrOfBoxex = 20; - privData->modelCount = 3+nrOfBoxex; - myId += privData->modelCount; - int id = 0; - // add world model + int nrOfBoxex = 5; + int id = 100; + +// add world model ModelInitData modelData; Oyster::Math3D::Float4x4 translate; C_Object* obj; @@ -104,7 +107,8 @@ bool GameState::LoadModels(std::wstring mapFile) privData->object.push_back(obj); privData->object[privData->object.size() -1 ]->Init(modelData); - // add box model + +// add box model modelData.world = Oyster::Math3D::Float4x4::identity; modelData.modelPath = L"crate_colonists.dan"; @@ -120,89 +124,63 @@ bool GameState::LoadModels(std::wstring mapFile) privData->object[privData->object.size() -1 ]->Init(modelData); modelData.world = Oyster::Math3D::Float4x4::identity; } - - // add crystal model - modelData.world = Oyster::Math3D::Float4x4::identity; - translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(10, 301, 0)); - - modelData.world = modelData.world * translate; - modelData.visible = true; - modelData.modelPath = L"crystalformation_b.dan"; - modelData.id = id++; - // load models - obj = new C_Player(); - privData->object.push_back(obj); - privData->object[privData->object.size() -1 ]->Init(modelData); - - // add house model - modelData.world = Oyster::Math3D::Float4x4::identity; - translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(-50, 290, 0)); - Oyster::Math3D::Float4x4 rot = Oyster::Math3D::RotationMatrix(Oyster::Math::Float3(0 ,Utility::Value::Radian(90.0f), 0)); - - modelData.world = modelData.world * translate * rot; - modelData.visible = true; - modelData.modelPath = L"building_corporation.dan"; - modelData.id = id++; - // load models - obj = new C_Player(); - privData->object.push_back(obj); - privData->object[privData->object.size() -1 ]->Init(modelData); - - - // add player model - modelData.world = Oyster::Math3D::Float4x4::identity; - translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(0, 320, 0)); - - modelData.world = modelData.world * translate; - modelData.visible = true; - modelData.modelPath = L"char_still_sizeref.dan"; - modelData.id = id++; - // load models - obj = new C_Player(); - privData->object.push_back(obj); - privData->object[privData->object.size() -1 ]->Init(modelData); - - // add player model 2 - modelData.world = Oyster::Math3D::Float4x4::identity; - translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(50, 320, 0)); - - modelData.world = modelData.world * translate; - modelData.visible = true; - modelData.modelPath = L"char_still_sizeref.dan"; - modelData.id = id++; - // load models - obj = new C_Player(); - privData->object.push_back(obj); - privData->object[privData->object.size() -1 ]->Init(modelData); - - // add jumppad - modelData.world = Oyster::Math3D::Float4x4::identity; - translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(4, 300.3, 0)); - //Oyster::Math3D::RotationMatrix_AxisZ() - modelData.world = modelData.world * translate; - modelData.visible = true; - modelData.modelPath = L"jumppad_round.dan"; - modelData.id = id++; - // load models - obj = new C_Player(); - privData->object.push_back(obj); - privData->object[privData->object.size() -1 ]->Init(modelData); - - // add sky sphere - modelData.world = Oyster::Math3D::Float4x4::identity; - translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(0, 0, 0)); - //Oyster::Math3D::RotationMatrix_AxisZ() - modelData.world = modelData.world * translate; - modelData.world.v[0].x = 800; - modelData.world.v[1].y = 800; - modelData.world.v[2].z = 800; - modelData.visible = true; - modelData.modelPath = L"skysphere.dan"; - modelData.id = id++; - // load models - obj = new C_Player(); - privData->object.push_back(obj); - privData->object[privData->object.size() -1 ]->Init(modelData); +// +//// add crystal model +// modelData.world = Oyster::Math3D::Float4x4::identity; +// translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(10, 301, 0)); +// +// modelData.world = modelData.world * translate; +// modelData.visible = true; +// modelData.modelPath = L"crystalformation_b.dan"; +// modelData.id = id++; +// // load models +// obj = new C_Player(); +// privData->object.push_back(obj); +// privData->object[privData->object.size() -1 ]->Init(modelData); +// +//// add house model +// modelData.world = Oyster::Math3D::Float4x4::identity; +// translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(-50, 290, 0)); +// Oyster::Math3D::Float4x4 rot = Oyster::Math3D::RotationMatrix(Oyster::Math::Float3(0 ,Utility::Value::Radian(90.0f), 0)); +// +// modelData.world = modelData.world * translate * rot; +// modelData.visible = true; +// modelData.modelPath = L"building_corporation.dan"; +// modelData.id = id++; +// // load models +// obj = new C_Player(); +// privData->object.push_back(obj); +// privData->object[privData->object.size() -1 ]->Init(modelData); +// +// +// // add jumppad +// modelData.world = Oyster::Math3D::Float4x4::identity; +// translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(4, 300.3, 0)); +// //Oyster::Math3D::RotationMatrix_AxisZ() +// modelData.world = modelData.world * translate; +// modelData.visible = true; +// modelData.modelPath = L"jumppad_round.dan"; +// modelData.id = id++; +// // load models +// obj = new C_Player(); +// privData->object.push_back(obj); +// privData->object[privData->object.size() -1 ]->Init(modelData); +// +// // add sky sphere +// modelData.world = Oyster::Math3D::Float4x4::identity; +// translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(0, 0, 0)); +// //Oyster::Math3D::RotationMatrix_AxisZ() +// modelData.world = modelData.world * translate; +// modelData.world.v[0].x = 800; +// modelData.world.v[1].y = 800; +// modelData.world.v[2].z = 800; +// modelData.visible = true; +// modelData.modelPath = L"skysphere.dan"; +// modelData.id = id++; +// // load models +// obj = new C_Player(); +// privData->object.push_back(obj); +// privData->object[privData->object.size() -1 ]->Init(modelData); return true; } @@ -215,7 +193,7 @@ bool GameState::InitCamera(Oyster::Math::Float3 startPos) camera->LookAt(pos, dir, up); camera->SetLens(3.14f/2, 1024/768, 1, 1000); - privData->proj = Oyster::Math3D::ProjectionMatrix_Perspective(Oyster::Math::pi/4,1024.0f/768.0f,.1f,1000); + privData->proj = Oyster::Math3D::ProjectionMatrix_Perspective(Oyster::Math::pi / 4, 1024.0f / 768.0f, .1f,1000); //privData->proj = Oyster::Math3D::ProjectionMatrix_Orthographic(1024, 768, 1, 1000); Oyster::Graphics::API::SetProjection(privData->proj); camera->UpdateViewMatrix(); @@ -225,15 +203,55 @@ bool GameState::InitCamera(Oyster::Math::Float3 startPos) privData->view = Oyster::Math3D::InverseOrientationMatrix(privData->view); return true; } -void GameState::setClientId(int id) +void GameState::InitiatePlayer(int id, std::wstring modelName, Oyster::Math::Float4x4 world) { myId = id; + + ModelInitData modelData; + C_Object* obj; + modelData.visible = true; + modelData.world = world; + modelData.modelPath = modelName; + modelData.id = myId; + + obj = new C_Player(); + privData->object.push_back(obj); + privData->object[privData->object.size() -1 ]->Init(modelData); + + //printf("Move message recieved!"); + Oyster::Math::Float3 right = Oyster::Math::Float3(world[0], world[1], world[2]); + Oyster::Math::Float3 up = Oyster::Math::Float3(world[4], world[5], world[6]); + Oyster::Math::Float3 objForward = (Oyster::Math::Float3(world[8], world[9], world[10])); + Oyster::Math::Float3 pos = Oyster::Math::Float3(world[12], world[13], world[14]); + + Oyster::Math::Float3 cameraLook = camera->GetLook(); + Oyster::Math::Float3 cameraUp = camera->GetUp(); + + + + /*Oyster::Math::Float3 newUp = cameraUp.Dot(up); + up *= newUp; + up.Normalize(); + Oyster::Math::Float3 newLook = up.Cross(right); + newLook.Normalize();*/ + + camera->setRight(right); + camera->setUp(up); + camera->setLook(objForward); + + up *= 2; + objForward *= -3; + Oyster::Math::Float3 cameraPos = up + pos + objForward; + camera->SetPosition(cameraPos); + + camera->UpdateViewMatrix(); + } GameClientState::ClientState GameState::Update(float deltaTime, InputClass* KeyInput) { switch (privData->state) { - case gameStateState_loading: + case gameStateState_loading: //Will this ever happen in this scope?? { // load map // wait for all players @@ -465,9 +483,10 @@ void GameState::Protocol( ObjPos* pos ) if(privData->object[i]->GetId() == pos->object_ID) { privData->object[i]->setPos(world); - Oyster::Math::Float3 pos = Oyster::Math::Float3(0, 600, 15); - if(i == myId) // playerobj + Oyster::Math::Float3 position = Oyster::Math::Float3(0, 605, 15); + if(pos->object_ID == myId) // playerobj { + //printf("Move message recieved!"); Oyster::Math::Float3 right = Oyster::Math::Float3(world[0], world[1], world[2]); Oyster::Math::Float3 up = Oyster::Math::Float3(world[4], world[5], world[6]); Oyster::Math::Float3 objForward = (Oyster::Math::Float3(world[8], world[9], world[10])); @@ -491,12 +510,13 @@ void GameState::Protocol( ObjPos* pos ) up *= 1; objForward *= -2; - Oyster::Math::Float3 cameraPos = pos + up + objForward; - camera->SetPosition(cameraPos); + Oyster::Math::Float3 cameraPos = position + up + objForward; + //camera->SetPosition(cameraPos); - camera->UpdateViewMatrix(); + } - camera->SetPosition(pos); + camera->SetPosition(position); + //camera->UpdateViewMatrix(); } } } diff --git a/Code/Game/DanBiasGame/GameClientState/GameState.h b/Code/Game/DanBiasGame/GameClientState/GameState.h index d555134c..2cff9ed9 100644 --- a/Code/Game/DanBiasGame/GameClientState/GameState.h +++ b/Code/Game/DanBiasGame/GameClientState/GameState.h @@ -37,8 +37,8 @@ public: GameClientState::ClientState Update(float deltaTime, InputClass* KeyInput) override; bool LoadModels(std::wstring mapFile) ; bool InitCamera(Oyster::Math::Float3 startPos) ; + void InitiatePlayer(int id, std::wstring modelName, Oyster::Math::Float4x4 world); gameStateState LoadGame(); - void setClientId(int id); void readKeyInput(InputClass* KeyInput); bool Render()override; bool Release()override; diff --git a/Code/Game/DanBiasGame/GameClientState/LobbyState.cpp b/Code/Game/DanBiasGame/GameClientState/LobbyState.cpp index cce1dfcd..34e6f429 100644 --- a/Code/Game/DanBiasGame/GameClientState/LobbyState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/LobbyState.cpp @@ -5,6 +5,7 @@ #include "C_obj/C_StaticObj.h" #include "C_obj/C_DynamicObj.h" #include +#include using namespace DanBias::Client; @@ -88,9 +89,15 @@ GameClientState::ClientState LobbyState::Update(float deltaTime, InputClass* Key // send data to server // check data from server - if( KeyInput->IsKeyPressed(DIK_G)) + if(GameServerAPI::ServerIsRunning() && GameServerAPI::ServerIsRunning()) //May be a problem if server is not shut down properly after lan session. { - return ClientState_Game; + if( KeyInput->IsKeyPressed(DIK_G)) + { + if(!DanBias::GameServerAPI::GameStart()) + { + //this->nwClient->Send(GameLogic::Protocol_LobbyStartGame()); + } + } } return ClientState_Same; diff --git a/Code/Game/DanBiasGame/GameClientState/LoginState.cpp b/Code/Game/DanBiasGame/GameClientState/LoginState.cpp index 4a244a8b..e2392558 100644 --- a/Code/Game/DanBiasGame/GameClientState/LoginState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/LoginState.cpp @@ -105,7 +105,7 @@ GameClientState::ClientState LoginState::Update(float deltaTime, InputClass* Key DanBias::GameServerAPI::ServerInitiate(desc); DanBias::GameServerAPI::ServerStart(); // my ip - nwClient->Connect(15151, "127.0.0.1"); + nwClient->Connect(15152, "127.0.0.1"); if (!nwClient->IsConnected()) { @@ -118,7 +118,7 @@ GameClientState::ClientState LoginState::Update(float deltaTime, InputClass* Key if( KeyInput->IsKeyPressed(DIK_J)) { // game ip - nwClient->Connect(15151, "127.0.0.1"); + nwClient->Connect(15152, "127.0.0.1"); if (!nwClient->IsConnected()) { diff --git a/Code/Game/GameLogic/AttatchmentSocket.cpp b/Code/Game/GameLogic/AttatchmentSocket.cpp index 4a663bef..7a8076b1 100644 --- a/Code/Game/GameLogic/AttatchmentSocket.cpp +++ b/Code/Game/GameLogic/AttatchmentSocket.cpp @@ -14,7 +14,10 @@ AttatchmentSocket::AttatchmentSocket(void) AttatchmentSocket::~AttatchmentSocket(void) { - + if(this->attatchment) + delete this->attatchment; + + this->attatchment = 0; } IAttatchment* AttatchmentSocket::GetAttatchment() diff --git a/Code/Game/GameLogic/CollisionManager.cpp b/Code/Game/GameLogic/CollisionManager.cpp index 922ab7fe..9c6f6aca 100644 --- a/Code/Game/GameLogic/CollisionManager.cpp +++ b/Code/Game/GameLogic/CollisionManager.cpp @@ -83,7 +83,7 @@ using namespace GameLogic; if(kineticEnergyLoss > forceThreashHold) //should only take damage if the force is high enough { - damageDone = kineticEnergyLoss * 0.10f; + damageDone = (int)(kineticEnergyLoss * 0.10f); //player.DamageLife(damageDone); } diff --git a/Code/Game/GameLogic/Game.cpp b/Code/Game/GameLogic/Game.cpp index fe7a41c7..29287f76 100644 --- a/Code/Game/GameLogic/Game.cpp +++ b/Code/Game/GameLogic/Game.cpp @@ -68,12 +68,12 @@ void Game::GetAllPlayerPositions() const Game::PlayerData* Game::CreatePlayer() { // Find a free space in array or insert at end - int id = InsertObject(this->players, (PlayerData*)0); + int i = InsertObject(this->players, (PlayerData*)0); - this->players[id] = new PlayerData(); - //this->players[id]->player->GetRigidBody()->SetSubscription(Game::PhysicsOnMove); + this->players[i] = new PlayerData(); + //this->players[i]->player->GetRigidBody()->SetSubscription(Game::PhysicsOnMove); - return this->players[id]; + return this->players[i]; } Game::LevelData* Game::CreateLevel() @@ -93,7 +93,6 @@ void Game::CreateTeam() bool Game::NewFrame() { - for (unsigned int i = 0; i < this->players.Size(); i++) { if(this->players[i]->player) this->players[i]->player->BeginFrame(); @@ -104,31 +103,10 @@ bool Game::NewFrame() for (unsigned int i = 0; i < this->players.Size(); i++) { if(this->players[i]->player) this->players[i]->player->EndFrame(); - } - for (unsigned int i = 0; i < this->players.Size(); i++) - { - if(this->players[i]->player) this->players[i]->player->BeginFrame(); + gameInstance.onMoveFnc(this->players[i]); } - API::Instance().UpdateWorld(); - - for (unsigned int i = 0; i < this->players.Size(); i++) - { - if(this->players[i]->player) this->players[i]->player->EndFrame(); - } - for (unsigned int i = 0; i < this->players.Size(); i++) - { - if(this->players[i]->player) this->players[i]->player->BeginFrame(); - } - - API::Instance().UpdateWorld(); - - for (unsigned int i = 0; i < this->players.Size(); i++) - { - if(this->players[i]->player) this->players[i]->player->EndFrame(); - } - - gameInstance.onMoveFnc(this->level); + return true; } @@ -143,24 +121,21 @@ void Game::SetFrameTimeLength( float seconds ) this->frameTime = seconds; } -void Game::SetSubscription(GameEvent::ObjectEventFunctionType type, GameEvent::ObjectEventFunction functionPointer) +void Game::SetSubscription(GameEvent::ObjectMovedFunction functionPointer) { - switch (type) - { - case GameLogic::GameEvent::ObjectEventFunctionType_OnMove: - this->onMoveFnc = functionPointer; - break; - case GameLogic::GameEvent::ObjectEventFunctionType_OnDead: - this->onDisableFnc = functionPointer; - break; - } - + this->onMoveFnc = functionPointer; +} +void Game::SetSubscription(GameEvent::ObjectDisabledFunction functionPointer) +{ + this->onDisableFnc = functionPointer; + } bool Game::Initiate() { API::Instance().Init(); //API::Instance().SetSubscription(Game::PhysicsOnDestroy); + //API::Instance().SetFrameTimeLength(this->frameTime); this->initiated = true; return true; } @@ -183,6 +158,6 @@ void Game::PhysicsOnMove(const ICustomBody *object) } void Game::PhysicsOnDestroy(::Utility::DynamicMemory::UniquePointer proto) { - if(gameInstance.onDisableFnc) gameInstance.onDisableFnc(0); + if(gameInstance.onDisableFnc) gameInstance.onDisableFnc(0, 0); } diff --git a/Code/Game/GameLogic/Game.h b/Code/Game/GameLogic/Game.h index b57520e0..2ae96ce3 100644 --- a/Code/Game/GameLogic/Game.h +++ b/Code/Game/GameLogic/Game.h @@ -69,7 +69,8 @@ namespace GameLogic bool NewFrame() override; void SetFPS( int FPS ) override; void SetFrameTimeLength( float seconds ) override; - void SetSubscription(GameEvent::ObjectEventFunctionType type, GameEvent::ObjectEventFunction functionPointer) override; + void SetSubscription(GameEvent::ObjectMovedFunction functionPointer) override; + void SetSubscription(GameEvent::ObjectDisabledFunction functionPointer) override; bool Initiate() override; float GetFrameTime() const; @@ -81,8 +82,8 @@ namespace GameLogic LevelData* level; float frameTime; bool initiated; - GameEvent::ObjectEventFunction onDisableFnc; - GameEvent::ObjectEventFunction onMoveFnc; + GameEvent::ObjectDisabledFunction onDisableFnc; + GameEvent::ObjectMovedFunction onMoveFnc; }; } diff --git a/Code/Game/GameLogic/GameAPI.h b/Code/Game/GameLogic/GameAPI.h index 53931063..3505b123 100644 --- a/Code/Game/GameLogic/GameAPI.h +++ b/Code/Game/GameLogic/GameAPI.h @@ -23,16 +23,8 @@ namespace GameLogic */ namespace GameEvent { - /** - * The type of event to listen on. - */ - enum ObjectEventFunctionType - { - ObjectEventFunctionType_OnMove, - ObjectEventFunctionType_OnDead, - }; - - typedef void(*ObjectEventFunction)(IObjectData* object); // Callback method that recieves and object + typedef void(*ObjectMovedFunction)(IObjectData* object); // Callback method that recieves and object + typedef void(*ObjectDisabledFunction)(IObjectData* object, float seconds); // Callback method that recieves and object //etc... }; @@ -147,17 +139,22 @@ namespace GameLogic /** Set the frame time in fps * @param FPS The fps to set */ - virtual void SetFPS( int FPS = 60 ) = 0; + virtual void SetFPS( int FPS = 120 ) = 0; /** Set the frames time in seconds * @param seconds The frame length */ - virtual void SetFrameTimeLength( float seconds ) = 0; + virtual void SetFrameTimeLength( float seconds = (1.0f/120.0f) ) = 0; /** Set a specific object event subscription callback * @param */ - virtual void SetSubscription(GameEvent::ObjectEventFunctionType type, GameEvent::ObjectEventFunction functionPointer) = 0; + virtual void SetSubscription(GameEvent::ObjectMovedFunction functionPointer) = 0; + + /** Set a specific object event subscription callback + * @param + */ + virtual void SetSubscription(GameEvent::ObjectDisabledFunction functionPointer) = 0; }; } diff --git a/Code/Game/GameLogic/GameLogic.vcxproj.user b/Code/Game/GameLogic/GameLogic.vcxproj.user index 4b847ee6..2e28d6f7 100644 --- a/Code/Game/GameLogic/GameLogic.vcxproj.user +++ b/Code/Game/GameLogic/GameLogic.vcxproj.user @@ -1,7 +1,7 @@  - false + true $(OutDir) diff --git a/Code/Game/GameLogic/Level.cpp b/Code/Game/GameLogic/Level.cpp index 9c735c48..e15d9efa 100644 --- a/Code/Game/GameLogic/Level.cpp +++ b/Code/Game/GameLogic/Level.cpp @@ -1,5 +1,6 @@ #include "Level.h" #include "CollisionManager.h" +#include "Game.h" using namespace GameLogic; using namespace Utility::DynamicMemory; @@ -50,6 +51,7 @@ void Level::InitiateLevel(float radius) z /= norm; } + 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); @@ -58,24 +60,23 @@ void Level::InitiateLevel(float radius) state.restitutionCoeff = 0.2f; rigidBody->SetState(state); levelObj = new StaticObject(rigidBody, LevelCollisionBefore, LevelCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_WORLD); + 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, 0, 0, 1), Oyster::Math::Float3(0, 605 + i*5, 5), 5); + 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, 605 + i*5, -10), 5); this->dynamicObjects.Push(new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX)); + this->dynamicObjects[i]->objectID = idCount++; rigidBody_TestBox->SetCustomTag(this->dynamicObjects[i]); } - offset += nrOfBoxex; + /*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); @@ -100,26 +101,26 @@ void Level::InitiateLevel(float radius) this->dynamicObjects.Push(new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX)); rigidBody_TestBox->SetCustomTag(this->dynamicObjects[i]); - } + }*/ - // add crystal + //// add crystal - ICustomBody* rigidBody_Crystal = API::Instance().AddCollisionBox(Oyster::Math::Float3(0.5f, 0.5f, 0.5f), Oyster::Math::Float4(0, 0, 0, 1), Oyster::Math::Float3(10, 605, 0), 5); + //ICustomBody* rigidBody_Crystal = API::Instance().AddCollisionBox(Oyster::Math::Float3(0.5f, 0.5f, 0.5f), Oyster::Math::Float4(0, 0, 0, 1), Oyster::Math::Float3(10, 605, 0), 5); - this->dynamicObjects.Push(new DynamicObject(rigidBody_Crystal,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX)); - rigidBody_Crystal->SetCustomTag(this->dynamicObjects[nrOfBoxex]); + //this->dynamicObjects.Push(new DynamicObject(rigidBody_Crystal,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX)); + //rigidBody_Crystal->SetCustomTag(this->dynamicObjects[nrOfBoxex]); - + // - // add house - ICustomBody* rigidBody_House =API::Instance().AddCollisionBox(Oyster::Math::Float3(0.5f, 0.5f, 0.5f), Oyster::Math::Float4(0, 0, 0, 1), Oyster::Math::Float3(10, 905, 0), 0); - this->staticObjects.Push(new StaticObject(rigidBody_House,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_GENERIC)); - rigidBody_House->SetCustomTag(this->staticObjects[0]); + //// add house + //ICustomBody* rigidBody_House =API::Instance().AddCollisionBox(Oyster::Math::Float3(0.5f, 0.5f, 0.5f), Oyster::Math::Float4(0, 0, 0, 1), Oyster::Math::Float3(10, 905, 0), 0); + //this->staticObjects.Push(new StaticObject(rigidBody_House,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_GENERIC)); + //rigidBody_House->SetCustomTag(this->staticObjects[0]); } void Level::AddPlayerToTeam(Player *player, int teamID) @@ -154,4 +155,6 @@ void Level::PhysicsOnMoveLevel(const ICustomBody *object) { // function call from physics update when object was moved Object* temp = (Object*)object->GetCustomTag(); + ((Game*)&Game::Instance())->onMoveFnc(temp); + } diff --git a/Code/Game/GameLogic/LevelLoader/LevelParser.cpp b/Code/Game/GameLogic/LevelLoader/LevelParser.cpp index 088c3916..33567cc9 100644 --- a/Code/Game/GameLogic/LevelLoader/LevelParser.cpp +++ b/Code/Game/GameLogic/LevelLoader/LevelParser.cpp @@ -1,3 +1,7 @@ +///////////////////////////////////// +// Created by Pontus Fransson 2013 // +///////////////////////////////////// + #include "LevelParser.h" #include "Loader.h" @@ -9,7 +13,7 @@ using namespace Utility::DynamicMemory; LevelParser::LevelParser() { - formatVersion.formatVersionMajor = 1; + formatVersion.formatVersionMajor = 2; formatVersion.formatVersionMinor = 0; } @@ -29,35 +33,100 @@ std::vector> LevelParser::Parse(std::string filen char* buffer = (char*)loader.LoadFile(filename.c_str(), bufferSize); //Read format version - FormatVersion levelFormatVersion; + LevelLoaderInternal::FormatVersion levelFormatVersion; ParseObject(&buffer[counter], &levelFormatVersion, sizeof(levelFormatVersion)); counter += sizeof(levelFormatVersion); if(this->formatVersion != levelFormatVersion) { //Do something if it's not the same version + + //Returns an empty vector, because it will most likely fail to read the level format. + return objects; } while(counter < bufferSize) { //Get typeID - ObjectTypeHeader typeID; + ObjectType typeID; ParseObject(&buffer[counter], &typeID, sizeof(typeID)); - switch((int)typeID.typeID) + switch((int)typeID) { case ObjectType_LevelMetaData: { - LevelMetaData* header = new LevelMetaData; - ParseLevelMetaData(&buffer[counter], *header, counter); + SmartPointer header = new LevelMetaData; + ParseLevelMetaData(&buffer[counter], *(LevelMetaData*)header.Get(), counter); objects.push_back(header); break; } - //This is by design, static and dynamic is using the same converter. Do not add anything inbetween them. + //This is by design, static and dynamic is using the same converter. Do not add anything inbetween them. + //Unless they are changed to not be the same. case ObjectType_Static: case ObjectType_Dynamic: { - ObjectHeader* header = new ObjectHeader; - ParseObject(&buffer[counter], *header, counter); - objects.push_back(header); + //Get specialType. + ObjectSpecialType specialType; + ParseObject(&buffer[counter+4], &specialType, sizeof(typeID)); + + switch(specialType) + { + //These three does not have any specail variables at this time. + //There for they are using the same 'parser'. + case ObjectSpecialType_World: + case ObjectSpecialType_Building: + case ObjectSpecialType_Damaging: + case ObjectSpecialType_Explosive: + { + ObjectHeader* header = new ObjectHeader; + ParseObject(&buffer[counter], *header, counter); + objects.push_back(header); + + break; + } + case ObjectSpecialType_JumpPad: + { + JumpPadAttributes* header = new JumpPadAttributes; + ParseObject(&buffer[counter], *header, counter); + + //Read the spec + ParseObject(&buffer[counter], header->direction, 16); + objects.push_back(header); + + break; + } + case ObjectSpecialType_BoostPad: + { + JumpPadAttributes* header = new JumpPadAttributes; + ParseObject(&buffer[counter], *header, counter); + + ParseObject(&buffer[counter], header->direction, 16); + objects.push_back(header); + + break; + } + case ObjectSpecialType_Portal: + { + PortalAttributes* header = new PortalAttributes; + ParseObject(&buffer[counter], *header, counter); + + ParseObject(&buffer[counter], header->destination, 12); + objects.push_back(header); + + break; + } + case ObjectSpecialType_SpawnPoint: + { + SpawnPointAttributes* header = new SpawnPointAttributes; + ParseObject(&buffer[counter], *header, counter); + + ParseObject(&buffer[counter], header->spawnPosition, 12); + objects.push_back(header); + + break; + } + default: + //Couldn't find specialType + break; + } break; } @@ -68,7 +137,12 @@ std::vector> LevelParser::Parse(std::string filen //Get Light type ParseObject(&buffer[counter+4], &lightType, sizeof(lightType)); - switch(lightType) + //We only support PointLight for now. + BasicLight* header = new BasicLight; + ParseObject(&buffer[counter], header, sizeof(*header)); + counter += sizeof(*header); + objects.push_back(header); + /*switch(lightType) { case LightType_PointLight: { @@ -98,7 +172,7 @@ std::vector> LevelParser::Parse(std::string filen //Undefined LightType. break; } - break; + break;*/ } default: //Couldn't find typeID. FAIL!!!!!! @@ -123,21 +197,25 @@ LevelMetaData LevelParser::ParseHeader(std::string filename) char* buffer = (char*)loader.LoadFile(filename.c_str(), bufferSize); //Read format version - FormatVersion levelFormatVersion; + LevelLoaderInternal::FormatVersion levelFormatVersion; ParseObject(&buffer[counter], &levelFormatVersion, sizeof(formatVersion)); counter += sizeof(levelFormatVersion); if(this->formatVersion != levelFormatVersion) { //Do something if it's not the same version + + //Returns an empty levelHeader with ObjectType_Unknown. + //Because it will not be able to read another version of the level format. + return levelHeader; } //Find the header in the returned string. while(counter < bufferSize) { - ObjectTypeHeader typeID; + ObjectType typeID; ParseObject(&buffer[counter], &typeID, sizeof(typeID)); - switch(typeID.typeID) + switch(typeID) { case ObjectType_LevelMetaData: ParseLevelMetaData(&buffer[counter], levelHeader, counter); @@ -149,6 +227,24 @@ LevelMetaData LevelParser::ParseHeader(std::string filename) { ObjectHeader header; ParseObject(&buffer[counter], header, counter); + + switch(header.specialTypeID) + { + case ObjectSpecialType_JumpPad: + counter += sizeof(16); + break; + case ObjectSpecialType_BoostPad: + counter += sizeof(16); + break; + case ObjectSpecialType_Portal: + counter += sizeof(12); + break; + case ObjectSpecialType_SpawnPoint: + counter += sizeof(12); + break; + default: + break; + } break; } @@ -157,6 +253,9 @@ LevelMetaData LevelParser::ParseHeader(std::string filename) LightType lightType; ParseObject(&buffer[counter+4], &lightType, sizeof(lightType)); + //We only support pointlight for now. + counter += sizeof(BasicLight); + /* switch(lightType) { case LightType_PointLight: @@ -177,7 +276,7 @@ LevelMetaData LevelParser::ParseHeader(std::string filename) default: //Undefined LightType. break; - } + }*/ } default: diff --git a/Code/Game/GameLogic/LevelLoader/LevelParser.h b/Code/Game/GameLogic/LevelLoader/LevelParser.h index 9ad30642..346b75b5 100644 --- a/Code/Game/GameLogic/LevelLoader/LevelParser.h +++ b/Code/Game/GameLogic/LevelLoader/LevelParser.h @@ -23,7 +23,7 @@ namespace GameLogic LevelMetaData ParseHeader(std::string filename); private: - FormatVersion formatVersion; + LevelLoaderInternal::FormatVersion formatVersion; }; } diff --git a/Code/Game/GameLogic/LevelLoader/ObjectDefines.h b/Code/Game/GameLogic/LevelLoader/ObjectDefines.h index 8287dafb..d87e42b2 100644 --- a/Code/Game/GameLogic/LevelLoader/ObjectDefines.h +++ b/Code/Game/GameLogic/LevelLoader/ObjectDefines.h @@ -9,7 +9,7 @@ namespace GameLogic /************************************ Enums *************************************/ - + enum ObjectType { ObjectType_LevelMetaData, @@ -23,6 +23,21 @@ namespace GameLogic ObjectType_Unknown = -1 }; + enum ObjectSpecialType + { + ObjectSpecialType_World, //Always the main celestial body + ObjectSpecialType_Building, + ObjectSpecialType_Damaging, + ObjectSpecialType_Explosive, + ObjectSpecialType_JumpPad, + ObjectSpecialType_BoostPad, + ObjectSpecialType_Portal, + ObjectSpecialType_SpawnPoint, + + ObjectSpecialType_Count, + ObjectSpecialType_Unknown = -1 + }; + enum UsePhysics { UsePhysics_UseFullPhysics, @@ -38,16 +53,18 @@ namespace GameLogic { CollisionGeometryType_Box, CollisionGeometryType_Sphere, + CollisionGeometryType_Cylinder, CollisionGeometryType_Count, CollisionGeometryType_Unknown = -1 }; + //Only supports Pointlight right now. enum LightType { LightType_PointLight, - LightType_DirectionalLight, - LightType_SpotLight, + //LightType_DirectionalLight, + //LightType_SpotLight, LightType_Count, LightType_Unknown = -1 @@ -80,38 +97,93 @@ namespace GameLogic /************************************ Structs *************************************/ - - struct FormatVersion + namespace LevelLoaderInternal { - unsigned int formatVersionMajor; - unsigned int formatVersionMinor; - - bool operator ==(const FormatVersion& obj) + struct FormatVersion { - return (this->formatVersionMajor != obj.formatVersionMajor && this->formatVersionMinor != obj.formatVersionMinor); - } + unsigned int formatVersionMajor; + unsigned int formatVersionMinor; + + FormatVersion() + : formatVersionMajor(0), formatVersionMinor(0) + {} - bool operator !=(const FormatVersion& obj) - { - return !(*this == obj); - } - }; + FormatVersion(unsigned int major, unsigned int minor) + : formatVersionMajor(major), formatVersionMinor(minor) + {} + + bool operator ==(const FormatVersion& obj) + { + return (this->formatVersionMajor == obj.formatVersionMajor && this->formatVersionMinor == obj.formatVersionMinor); + } + + bool operator !=(const FormatVersion& obj) + { + return !(*this == obj); + } + }; + } struct ObjectTypeHeader { ObjectType typeID; + + //Unless this is here the object destructor wont be called. + virtual ~ObjectTypeHeader(){} }; - struct PhysicsObject + namespace LevelLoaderInternal { - UsePhysics usePhysics; - float mass; - float inertiaMagnitude[3]; - float inertiaRotation[3]; - float frictionCoeffStatic; - float frictionCoeffDynamic; - CollisionGeometryType geometryType; - }; + const FormatVersion boundingVolumeVersion(1, 0); + + struct BoundingVolumeBase + { + float position[3]; + }; + + struct BoundingVolumeBox : public BoundingVolumeBase + { + float size[3]; + float angularAxis[3]; + float angle; + }; + + struct BoundingVolumeSphere : public BoundingVolumeBase + { + float radius; + }; + + struct BoundingVolumeCylinder : public BoundingVolumeBase + { + float length; + float angularAxis[3]; + float angle; + float radius; + }; + + struct BoundingVolume + { + CollisionGeometryType geoType; + union + { + LevelLoaderInternal::BoundingVolumeBox box; + LevelLoaderInternal::BoundingVolumeSphere sphere; + LevelLoaderInternal::BoundingVolumeCylinder cylinder; + }; + }; + + struct PhysicsObject + { + UsePhysics usePhysics; + float mass; + float inertiaMagnitude[3]; + float inertiaRotation[3]; + float frictionCoeffStatic; + float frictionCoeffDynamic; + float restitutionCoeff; + BoundingVolume boundingVolume; + }; + } struct LevelMetaData : public ObjectTypeHeader { @@ -123,10 +195,15 @@ namespace GameLogic WorldSize worldSize; std::string overviewPicturePath; std::vector gameModesSupported; + + virtual ~LevelMetaData(){} + }; - struct ObjectHeader : public ObjectTypeHeader, public PhysicsObject + struct ObjectHeader : public ObjectTypeHeader, public LevelLoaderInternal::PhysicsObject { + //Special type id for special objects: portal, jumppad, exploding objects, etc. + ObjectSpecialType specialTypeID; //Model, std::string ModelFile; //Position @@ -136,8 +213,29 @@ namespace GameLogic float angle; //Scale float scale[3]; + + virtual ~ObjectHeader(){} }; + /************************************ + Special objects + *************************************/ + + struct JumpPadAttributes : public ObjectHeader + { + float direction[3]; + float power; + }; + + struct PortalAttributes : public ObjectHeader + { + float destination[3]; + }; + + struct SpawnPointAttributes : public ObjectHeader + { + float spawnPosition[3]; + }; /************************************ Lights @@ -145,12 +243,13 @@ namespace GameLogic struct BasicLight : public ObjectTypeHeader { - LightType lightType; - float ambientColor[3]; - float diffuseColor[3]; - float specularColor[3]; + LightType lightType; //Is not used right now + float color[3]; + float position[3]; + float raduis; + float intensity; }; - + /* We only support pointlight right now. struct PointLight : public BasicLight { float position[3]; @@ -166,7 +265,7 @@ namespace GameLogic float direction[3]; float range; float attenuation[3]; - }; + };*/ } #endif \ No newline at end of file diff --git a/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp b/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp index 95236c05..e8c055b3 100644 --- a/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp +++ b/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp @@ -4,6 +4,7 @@ #include "ParseFunctions.h" #include "../../../Misc/Packing/Packing.h" +#include "Loader.h" #include using namespace Oyster::Packing; @@ -29,6 +30,9 @@ namespace GameLogic memcpy(&header.typeID, &buffer[start], 4); start += 4; + memcpy(&header.specialTypeID, &buffer[start], 4); + start += 4; + memcpy(&tempSize, &buffer[start], 4); start += 4; @@ -36,13 +40,18 @@ namespace GameLogic header.ModelFile.assign(&tempName[0], &tempName[tempSize]); start += tempSize; + //The reset of the object struct //3 float[3], 1 float memcpy(&header.position, &buffer[start], 40); start += 40; - //2 float[3], 3 float, 2 uint + //Physics struct + //2 float[3], 4 float, 1 uint memcpy(&header.usePhysics, &buffer[start], 44); start += 44; + + //Read path for bounding volume + ParseBoundingVolume(&buffer[start], header.boundingVolume, start); size += start; } @@ -107,5 +116,55 @@ namespace GameLogic size += start; } + + void ParseBoundingVolume(char* buffer, LevelLoaderInternal::BoundingVolume& volume, int &size) + { + int start = 0; + int tempSize = 0; + char tempName[128]; + + memcpy(&tempSize, &buffer[start], 4); + start += 4; + + memcpy(&tempName, &buffer[start], tempSize); + + string fileName; + fileName.assign(&tempName[0], &tempName[tempSize]); + start += tempSize; + + //Läs in filen. + int fileLength = 0; + Loader loader; + char* buf = loader.LoadFile("E:\\Dropbox\\Programming\\Github\\Danbias\\Bin\\Content\\Worlds\\cgf\\"+ fileName, fileLength); + + LevelLoaderInternal::FormatVersion version; + memcpy(&version, &buffer[0], sizeof(version)); + + memcpy(&volume.geoType, &buf[8], sizeof(volume.geoType)); + //start += sizeof(volume.geoType); + + switch(volume.geoType) + { + case CollisionGeometryType_Box: + memcpy(&volume.box, &buf[12], sizeof(volume.box)); + //start += sizeof(volume.box); + break; + + case CollisionGeometryType_Sphere: + memcpy(&volume.sphere, &buf[12], sizeof(volume.sphere)); + //start += sizeof(volume.sphere); + break; + + case CollisionGeometryType_Cylinder: + memcpy(&volume.cylinder, &buf[12], sizeof(volume.cylinder)); + //start += sizeof(volume.cylinder); + break; + + default: + break; + } + + size += start; + } } } \ No newline at end of file diff --git a/Code/Game/GameLogic/LevelLoader/ParseFunctions.h b/Code/Game/GameLogic/LevelLoader/ParseFunctions.h index f68a9289..f66351b4 100644 --- a/Code/Game/GameLogic/LevelLoader/ParseFunctions.h +++ b/Code/Game/GameLogic/LevelLoader/ParseFunctions.h @@ -21,6 +21,7 @@ namespace GameLogic void ParseObject(char* buffer, void *header, int size); void ParseObject(char* buffer, ObjectHeader& header, int& size); void ParseLevelMetaData(char* buffer, LevelMetaData &header, int &size); + void ParseBoundingVolume(char* buffer, LevelLoaderInternal::BoundingVolume& volume, int &size); } } diff --git a/Code/Game/GameLogic/Object.cpp b/Code/Game/GameLogic/Object.cpp index e6a554f8..f099be18 100644 --- a/Code/Game/GameLogic/Object.cpp +++ b/Code/Game/GameLogic/Object.cpp @@ -102,8 +102,6 @@ Oyster::Physics::ICustomBody* Object::GetRigidBody() void Object::BeginFrame() { - - this->rigidBody->SetState(this->newPhysicsState); } // update physic diff --git a/Code/Game/GameLogic/Object.h b/Code/Game/GameLogic/Object.h index c484701c..48343c6a 100644 --- a/Code/Game/GameLogic/Object.h +++ b/Code/Game/GameLogic/Object.h @@ -43,7 +43,8 @@ namespace GameLogic static Oyster::Physics::ICustomBody::SubscriptMessage DefaultCollisionBefore(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj); static Oyster::Physics::ICustomBody::SubscriptMessage DefaultCollisionAfter(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss); - private: + + public: //TODO: Hax This should be private when level is dynamic OBJECT_TYPE type; int objectID; diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index 40102d2d..f407d8f0 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -208,7 +208,7 @@ void Player::DamageLife(int damage) { this->life = 0; playerState = PLAYER_STATE_DEAD; - this->gameInstance->onDisableFnc(this); + this->gameInstance->onDisableFnc(this, 0.0f); } } diff --git a/Code/Game/GameLogic/Player.h b/Code/Game/GameLogic/Player.h index 4f406e31..b7791a42 100644 --- a/Code/Game/GameLogic/Player.h +++ b/Code/Game/GameLogic/Player.h @@ -85,8 +85,8 @@ namespace GameLogic int teamID; Weapon *weapon; PLAYER_STATE playerState; - Oyster::Math::Float3 lookDir; - Oyster::Math::Float dx; + Oyster::Math::Float3 lookDir; //Duplicate in Object.h? + Oyster::Math::Float dx; //dx of what? bool hasTakenDamage; float invincibleCooldown; diff --git a/Code/Game/GameLogic/TeamManager.cpp b/Code/Game/GameLogic/TeamManager.cpp index d1379c63..e99dafe1 100644 --- a/Code/Game/GameLogic/TeamManager.cpp +++ b/Code/Game/GameLogic/TeamManager.cpp @@ -35,13 +35,11 @@ TeamManager::~TeamManager(void) void TeamManager::RespawnPlayerRandom(Player *player) { - // Whats going on here? - int teamID = player->GetTeamID(); // ? - // ? - Player *respawnOnThis = this->teams[teamID]->GetPlayer(0); // ? - // ? - player->Respawn(respawnOnThis->GetPosition()); // ? - // player->Respawn(player->GetPosition()); ? + int teamID = player->GetTeamID(); + + Player *respawnOnThis = this->teams[teamID]->GetPlayer(0); + + player->Respawn(respawnOnThis->GetPosition()); } void TeamManager::CreateTeam(int teamSize) diff --git a/Code/Game/GameLogic/Weapon.cpp b/Code/Game/GameLogic/Weapon.cpp index 19b53a31..e52fe8df 100644 --- a/Code/Game/GameLogic/Weapon.cpp +++ b/Code/Game/GameLogic/Weapon.cpp @@ -18,9 +18,17 @@ Weapon::Weapon() Weapon::Weapon(int MaxNrOfSockets,Player *owner) { + if(MaxNrOfSockets > 1) return; + + attatchmentSockets.Resize(MaxNrOfSockets); attatchmentSockets[0] = new AttatchmentSocket(); + for (int i = 0; i < MaxNrOfSockets; i++) + { + this->attatchmentSockets[i] = 0; + } + weaponState = WEAPON_STATE_IDLE; currentNrOfAttatchments = 0; selectedAttatchment = 0; @@ -36,7 +44,11 @@ Weapon::Weapon(int MaxNrOfSockets,Player *owner) Weapon::~Weapon(void) { - + for (unsigned int i = 0; i < this->attatchmentSockets.Size(); i++) + { + delete this->attatchmentSockets[i]; + this->attatchmentSockets[i] = 0; + } } /******************************************************** @@ -129,5 +141,7 @@ void Weapon::SelectAttatchment(int socketID) void Weapon::Update(float dt) { + if(!selectedAttatchment) return; + selectedAttatchment->Update(dt); } \ No newline at end of file diff --git a/Code/Game/GameProtocols/GameProtocols.vcxproj b/Code/Game/GameProtocols/GameProtocols.vcxproj index 826f9df4..4671f97f 100644 --- a/Code/Game/GameProtocols/GameProtocols.vcxproj +++ b/Code/Game/GameProtocols/GameProtocols.vcxproj @@ -69,25 +69,25 @@ $(SolutionDir)..\External\Lib\$(ProjectName)\ $(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ $(ProjectName)_$(PlatformShortName)D - $(SolutionDir)Network\NetworkAPI\;$(IncludePath) + $(SolutionDir)Network\NetworkAPI\;$(SolutionDir)Misc;$(IncludePath) $(SolutionDir)..\External\Lib\$(ProjectName)\ $(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ $(ProjectName)_$(PlatformShortName) - $(SolutionDir)Network\NetworkAPI\;$(IncludePath) + $(SolutionDir)Network\NetworkAPI\;$(SolutionDir)Misc;$(IncludePath) $(SolutionDir)..\External\Lib\$(ProjectName)\ $(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ $(ProjectName)_$(PlatformShortName)D - $(SolutionDir)Network\NetworkAPI\;$(IncludePath) + $(SolutionDir)Network\NetworkAPI\;$(SolutionDir)Misc;$(IncludePath) $(SolutionDir)..\External\Lib\$(ProjectName)\ $(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ $(ProjectName)_$(PlatformShortName) - $(SolutionDir)Network\NetworkAPI\;$(IncludePath) + $(SolutionDir)Network\NetworkAPI\;$(SolutionDir)Misc;$(IncludePath) diff --git a/Code/Game/GameProtocols/GeneralProtocols.h b/Code/Game/GameProtocols/GeneralProtocols.h index 02763ba0..db50b61f 100644 --- a/Code/Game/GameProtocols/GeneralProtocols.h +++ b/Code/Game/GameProtocols/GeneralProtocols.h @@ -24,23 +24,24 @@ namespace GameLogic this->protocol[1].type = Oyster::Network::NetAttributeType_Short; } - Protocol_General_Status(Oyster::Network::CustomNetProtocol& p) - { - this->protocol = p; - status = (States)p[1].value.netShort; - } Protocol_General_Status(States state) { this->protocol[0].value = protocol_General_Status; this->protocol[0].type = Oyster::Network::NetAttributeType_Short; - this->status = state; + this->protocol[1].type = Oyster::Network::NetAttributeType_Short; + this->status = state; } - Oyster::Network::CustomNetProtocol* GetProtocol() override + + Protocol_General_Status(Oyster::Network::CustomNetProtocol& p) + { + status = (States)this->protocol[1].value.netShort; + } + Oyster::Network::CustomNetProtocol GetProtocol() override { this->protocol[1].value = status; - return &protocol; + return protocol; } private: @@ -59,12 +60,12 @@ namespace GameLogic destination = p.Get(1).value.netInt; text = p.Get(2).value.netCharPtr; } - Oyster::Network::CustomNetProtocol* GetProtocol() override + Oyster::Network::CustomNetProtocol GetProtocol() override { this->protocol.Set(0, protocol_General_Text, Oyster::Network::NetAttributeType_Short); this->protocol.Set(1, destination, Oyster::Network::NetAttributeType_Int); this->protocol.Set(2, text); - return &protocol; + return protocol; } private: diff --git a/Code/Game/GameProtocols/LobbyProtocols.h b/Code/Game/GameProtocols/LobbyProtocols.h index 192d81f2..b57245ba 100644 --- a/Code/Game/GameProtocols/LobbyProtocols.h +++ b/Code/Game/GameProtocols/LobbyProtocols.h @@ -12,61 +12,111 @@ #include +/** OBS! +** It seems like if a string is set in the middle of a data set, +** the reciever will crach when trying to use the protocol. +** Only tested on Protocol_LobbyStartGame. +**/ + + namespace GameLogic { - /* struct Protocol_LobbyCreateGame :public Oyster::Network::CustomProtocolObject { - char* mapName; - char gameId; + short clientID; // The unuiqe id reprsenting a specific client + std::string modelName; + float worldMatrix[16]; Protocol_LobbyCreateGame() { - this->protocol[0].value = protocol_Lobby_Create; - this->protocol[0].type = Oyster::Network::NetAttributeType_Short; + int c = 0; + this->protocol[c].value = protocol_Lobby_Create; + this->protocol[c++].type = Oyster::Network::NetAttributeType_Short; - this->protocol[1].type = Oyster::Network::NetAttributeType_CharArray; - this->protocol[2].type = Oyster::Network::NetAttributeType_Char; + this->protocol[c++].type = Oyster::Network::NetAttributeType_Short; + for (int i = 0; i <= 16; i++) + { + this->protocol[c++].type = Oyster::Network::NetAttributeType_Float; + } + this->protocol[c++].type = Oyster::Network::NetAttributeType_CharArray; } - Protocol_LobbyCreateGame(Oyster::Network::CustomNetProtocol& o) + Protocol_LobbyCreateGame(short _clientID, std::string name, float world[16]) { - mapName = o[1].value.netCharPtr; - gameId = o[2].value.netChar; + int c = 0; + this->protocol[c].value = protocol_Lobby_Create; + this->protocol[c++].type = Oyster::Network::NetAttributeType_Short; + + this->protocol[c++].type = Oyster::Network::NetAttributeType_Short; + for (int i = 0; i <= 16; i++) + { + this->protocol[c++].type = Oyster::Network::NetAttributeType_Float; + } + + this->protocol[c++].type = Oyster::Network::NetAttributeType_CharArray; + + clientID = _clientID; + modelName = name; + memcpy(&worldMatrix[0], &world[0], sizeof(float) * 16); } - Oyster::Network::CustomNetProtocol* GetProtocol() override + Protocol_LobbyCreateGame(Oyster::Network::CustomNetProtocol o) { - protocol[1].value = mapName; - protocol[2].value = gameId; - return &protocol; + int c = 1; + clientID = o[c++].value.netInt; + for (int i = 0; i <= 16; i++) + { + this->worldMatrix[i] = o[c++].value.netFloat; + } + modelName.assign(o[c++].value.netCharPtr); + } + Oyster::Network::CustomNetProtocol GetProtocol() override + { + int c = 1; + protocol[c++].value = clientID; + + for (int i = 0; i <= 16; i++) + { + this->protocol[c++].value = this->worldMatrix[i]; + } + protocol.Set(c++, this->modelName); + return protocol; } private: Oyster::Network::CustomNetProtocol protocol; + }; - */ + struct Protocol_LobbyStartGame :public Oyster::Network::CustomProtocolObject { - short gameId; + float seconds; Protocol_LobbyStartGame() { this->protocol[0].value = protocol_Lobby_Start; this->protocol[0].type = Oyster::Network::NetAttributeType_Short; - - this->protocol[1].type = Oyster::Network::NetAttributeType_Short; + this->protocol[1].type = Oyster::Network::NetAttributeType_Float; + seconds = 0; + } + Protocol_LobbyStartGame(float _seconds) + { + this->protocol[0].value = protocol_Lobby_Start; + this->protocol[0].type = Oyster::Network::NetAttributeType_Short; + this->protocol[1].type = Oyster::Network::NetAttributeType_Float; + seconds = _seconds; } Protocol_LobbyStartGame(Oyster::Network::CustomNetProtocol& o) { - gameId = o[1].value.netInt; + seconds = o[1].value.netFloat; } - Oyster::Network::CustomNetProtocol* GetProtocol() override + Oyster::Network::CustomNetProtocol GetProtocol() override { - protocol[1].value = gameId; - return &protocol; + this->protocol[1].value = seconds; + return protocol; } private: Oyster::Network::CustomNetProtocol protocol; + }; struct Protocol_LobbyLogin :public Oyster::Network::CustomProtocolObject @@ -83,9 +133,9 @@ namespace GameLogic { } - Oyster::Network::CustomNetProtocol* GetProtocol() override + Oyster::Network::CustomNetProtocol GetProtocol() override { - return &protocol; + return protocol; } private: @@ -109,7 +159,7 @@ namespace GameLogic // this->protocol[1].type = Oyster::Network::NetAttributeType_Short; // value = p[1].value.netShort; // } - // Oyster::Network::CustomNetProtocol* GetProtocol() override + // Oyster::Network::CustomNetProtocol GetProtocol() override // { // protocol[1].value = value; // return &protocol; @@ -130,8 +180,8 @@ namespace GameLogic { } - Oyster::Network::CustomNetProtocol* GetProtocol() override - { return &protocol; } + Oyster::Network::CustomNetProtocol GetProtocol() override + { return protocol; } private: Oyster::Network::CustomNetProtocol protocol; @@ -175,7 +225,7 @@ namespace GameLogic list.Push(d); } } - Oyster::Network::CustomNetProtocol* GetProtocol() override + Oyster::Network::CustomNetProtocol GetProtocol() override { this->protocol[1].value = list.Size(); @@ -195,7 +245,7 @@ namespace GameLogic this->protocol.Set(a++, list[i].ip); } - return &protocol; + return protocol; } private: @@ -223,13 +273,13 @@ namespace GameLogic minorVersion = (int)p.Get(2).value.netInt; mapName = p.Get(3).value.netCharPtr; } - Oyster::Network::CustomNetProtocol* GetProtocol() override + Oyster::Network::CustomNetProtocol GetProtocol() override { this->protocol[1].value = majorVersion; this->protocol[2].value = minorVersion; this->protocol.Set(3, mapName.c_str()); - return &protocol; + return protocol; } private: @@ -254,7 +304,7 @@ namespace GameLogic // { // // } - // Oyster::Network::CustomNetProtocol* GetProtocol() override + // Oyster::Network::CustomNetProtocol GetProtocol() override // { // return &protocol; // } diff --git a/Code/Game/GameProtocols/ObjectProtocols.h b/Code/Game/GameProtocols/ObjectProtocols.h index b71599b1..5ce10b27 100644 --- a/Code/Game/GameProtocols/ObjectProtocols.h +++ b/Code/Game/GameProtocols/ObjectProtocols.h @@ -39,11 +39,11 @@ namespace GameLogic pickup_ID = pickupID; } - Oyster::Network::CustomNetProtocol* GetProtocol() override + Oyster::Network::CustomNetProtocol GetProtocol() override { this->protocol[1].value = object_ID; this->protocol[2].value = pickup_ID; - return &protocol; + return protocol; } private: @@ -80,11 +80,11 @@ namespace GameLogic object_ID = id; health = hp; } - Oyster::Network::CustomNetProtocol* GetProtocol() override + Oyster::Network::CustomNetProtocol GetProtocol() override { this->protocol[1].value = object_ID; this->protocol[2].value = health; - return &protocol; + return protocol; } private: @@ -129,14 +129,14 @@ namespace GameLogic object_ID = id; memcpy(&worldMatrix[0], &m[0], sizeof(float)*16); } - Oyster::Network::CustomNetProtocol* GetProtocol() override + Oyster::Network::CustomNetProtocol GetProtocol() override { this->protocol[1].value = object_ID; for (int i = 2; i <= 17; i++) { this->protocol[i].value = worldMatrix[i-2]; } - return &protocol; + return protocol; } private: @@ -179,14 +179,14 @@ namespace GameLogic object_ID = id; memcpy(&worldMatrix[0], &m[0], sizeof(float)*16); } - Oyster::Network::CustomNetProtocol* GetProtocol() override + Oyster::Network::CustomNetProtocol GetProtocol() override { this->protocol[1].value = object_ID; for (int i = 2; i <= 17; i++) { this->protocol[i].value = worldMatrix[i-2]; } - return &protocol; + return protocol; } private: @@ -221,11 +221,11 @@ namespace GameLogic object_ID = id; timer = time; } - Oyster::Network::CustomNetProtocol* GetProtocol() override + Oyster::Network::CustomNetProtocol GetProtocol() override { this->protocol[1].value = object_ID; this->protocol[2].value = timer; - return &protocol; + return protocol; } private: @@ -234,8 +234,9 @@ namespace GameLogic struct Protocol_ObjectCreate :public Oyster::Network::CustomProtocolObject { + //ObjectType type; //ie player, box or whatever int object_ID; - char *name; + std::string name; float worldMatrix[16]; Protocol_ObjectCreate() @@ -244,7 +245,7 @@ namespace GameLogic this->protocol[0].type = Oyster::Network::NetAttributeType_Short; this->protocol[1].type = Oyster::Network::NetAttributeType_Int; - this->protocol[2].type = Oyster::Network::NetAttributeType_CharArray; + this->protocol[2].type = Oyster::Network::NetAttributeType_CharArray; for (int i = 3; i <= 18; i++) { @@ -272,11 +273,11 @@ namespace GameLogic this->name = path; memcpy(&worldMatrix[0], &m[0], sizeof(float)*16); } - Oyster::Network::CustomNetProtocol* GetProtocol() override + Oyster::Network::CustomNetProtocol GetProtocol() override { this->protocol[1].value = object_ID; - this->protocol[2].value = name; + this->protocol.Set(2, name); this->protocol[3].value = worldMatrix[0]; this->protocol[4].value = worldMatrix[1]; this->protocol[5].value = worldMatrix[2]; @@ -297,7 +298,7 @@ namespace GameLogic - return &protocol; + return protocol; } private: diff --git a/Code/Game/GameProtocols/PlayerProtocols.h b/Code/Game/GameProtocols/PlayerProtocols.h index 2192b361..81e6fbb8 100644 --- a/Code/Game/GameProtocols/PlayerProtocols.h +++ b/Code/Game/GameProtocols/PlayerProtocols.h @@ -49,14 +49,14 @@ namespace GameLogic return *this; } - Oyster::Network::CustomNetProtocol* GetProtocol() override + Oyster::Network::CustomNetProtocol GetProtocol() override { this->protocol[1].value = bForward; this->protocol[2].value = bBackward; this->protocol[3].value = bLeft; this->protocol[4].value = bRight; - return &protocol; + return protocol; } private: @@ -98,7 +98,7 @@ namespace GameLogic return *this; } - Oyster::Network::CustomNetProtocol* GetProtocol() override + Oyster::Network::CustomNetProtocol GetProtocol() override { this->protocol[1].value = lookDirX; this->protocol[2].value = lookDirY; @@ -106,7 +106,7 @@ namespace GameLogic this->protocol[4].value = deltaX; - return &protocol; + return protocol; } private: @@ -131,9 +131,9 @@ namespace GameLogic { return *this; } - Oyster::Network::CustomNetProtocol* GetProtocol() override + Oyster::Network::CustomNetProtocol GetProtocol() override { - return &protocol; + return protocol; } private: @@ -168,12 +168,12 @@ namespace GameLogic utilityPressed = val[3].value.netBool; return *this; } - Oyster::Network::CustomNetProtocol* GetProtocol() override + Oyster::Network::CustomNetProtocol GetProtocol() override { this->protocol[1].value = primaryPressed; this->protocol[2].value = secondaryPressed; this->protocol[3].value = utilityPressed; - return &protocol; + return protocol; } private: @@ -200,10 +200,10 @@ namespace GameLogic hasJumped = val[1].value.netBool; return *this; } - Oyster::Network::CustomNetProtocol* GetProtocol() override + Oyster::Network::CustomNetProtocol GetProtocol() override { this->protocol[1].value = hasJumped; - return &protocol; + return protocol; } private: diff --git a/Code/Game/GameServer/GameClient.h b/Code/Game/GameServer/GameClient.h index 5db6efdb..a9c33cf3 100644 --- a/Code/Game/GameServer/GameClient.h +++ b/Code/Game/GameServer/GameClient.h @@ -24,14 +24,19 @@ namespace DanBias GameLogic::IPlayerData* ReleasePlayer(); Utility::DynamicMemory::SmartPointer GetClient(); Utility::DynamicMemory::SmartPointer ReleaseClient(); - int GetID() const; + float GetSinceLastResponse() const; + bool IsReady() const; bool Equals(const Oyster::Network::NetworkClient* c); + void SetReadyState(bool isReady); + void SetSinceLastResponse(float seconds); + private: GameLogic::IPlayerData* player; Utility::DynamicMemory::SmartPointer client; - int id; + bool isReady; + float secondsSinceLastResponse; }; }//End namespace DanBias diff --git a/Code/Game/GameServer/GameLobby.h b/Code/Game/GameServer/GameLobby.h index 8a421e1d..94cb0e3c 100644 --- a/Code/Game/GameServer/GameLobby.h +++ b/Code/Game/GameServer/GameLobby.h @@ -52,8 +52,10 @@ namespace DanBias private: Utility::WinTimer timer; float refreshFrequency; + GameSession gameSession; LobbyLevelData description; + Utility::DynamicMemory::SmartPointer sessionOwner; }; }//End namespace DanBias #endif // !DANBIASGAME_GAMELOBBY_H diff --git a/Code/Game/GameServer/GameServerAPI.h b/Code/Game/GameServer/GameServerAPI.h index e76b4264..7ceab867 100644 --- a/Code/Game/GameServer/GameServerAPI.h +++ b/Code/Game/GameServer/GameServerAPI.h @@ -32,9 +32,11 @@ namespace DanBias { char* serverName; int listenPort; + bool broadcast; //Not fully implemented! ServerInitDesc() : serverName("Game Server") - , listenPort(15151) + , listenPort(15152) + , broadcast(true) {}; }; struct GameServerInfo @@ -49,6 +51,7 @@ namespace DanBias static void ServerStop(); static void ServerUpdate(); static GameServerInfo ServerGetInfo(); + static bool ServerIsRunning(); static void GameSetMapId(const int& val); static void GameSetMaxClients(const int& val); diff --git a/Code/Game/GameServer/GameSession.h b/Code/Game/GameServer/GameSession.h index 899bc189..80d43a19 100644 --- a/Code/Game/GameServer/GameSession.h +++ b/Code/Game/GameServer/GameSession.h @@ -52,24 +52,27 @@ namespace DanBias * @param client The client to attach to the session */ bool Attach(Oyster::Network::NetClient client) override; + void CloseSession( bool dissconnectClients ) override; inline bool IsCreated() const { return this->isCreated; } inline bool IsRunning() const { return this->isRunning; } + operator bool() { return (this->isCreated && this->isCreated); } //Private member functions private: // TODO: find out what this method does.. void ClientEventCallback(Oyster::Network::NetEvent e) override; - //Sends a client to the owner, if obj is NULL then all clients is sent void SendToOwner(DanBias::GameClient* obj); - //Frame function, derived from IThreadObject + //Derived from IThreadObject + void ThreadEntry() override; bool DoWork ( ) override; + private: - void ParseProtocol (Oyster::Network::CustomNetProtocol& p, DanBias::GameClient* c); + void ParseProtocol ( Oyster::Network::CustomNetProtocol& p, DanBias::GameClient* c ); void Gameplay_PlayerMovement ( GameLogic::Protocol_PlayerMovement& p, DanBias::GameClient* c ); void Gameplay_PlayerLookDir ( GameLogic::Protocol_PlayerLook& p, DanBias::GameClient* c ); @@ -86,18 +89,23 @@ namespace DanBias void General_Text ( GameLogic::Protocol_General_Text& p, DanBias::GameClient* c ); //Callback method recieving from gamelogic - static void ObjectMove(GameLogic::IObjectData* movedObject); + static void ObjectMove ( GameLogic::IObjectData* movedObject ); + static void ObjectDisabled ( GameLogic::IObjectData* movedObject, float seconds ); //Private member variables private: Utility::DynamicMemory::DynamicArray> clients; + Utility::DynamicMemory::SmartPointer sessionOwner; Oyster::Thread::OysterThread worker; GameLogic::GameAPI& gameInstance; GameLogic::ILevelData *levelData; NetworkSession* owner; bool isCreated; bool isRunning; - Utility::WinTimer timer; + float logicFrameTime; + float networkFrameTime; + Utility::WinTimer logicTimer; + Utility::WinTimer networkTimer; GameDescription description; //TODO: Remove this uggly hax diff --git a/Code/Game/GameServer/Implementation/GameClient.cpp b/Code/Game/GameServer/Implementation/GameClient.cpp index 3f0c8308..3956fe57 100644 --- a/Code/Game/GameServer/Implementation/GameClient.cpp +++ b/Code/Game/GameServer/Implementation/GameClient.cpp @@ -11,19 +11,18 @@ using namespace Oyster::Network; using namespace DanBias; using namespace GameLogic; -static int gameClientIDCount = 1; GameClient::GameClient(SmartPointer client, GameLogic::IPlayerData* player) { this->client = client; - this->id = gameClientIDCount++; this->player = player; + isReady = false; } GameClient::~GameClient() { this->client->Disconnect(); this->player = 0; - this->id = -1; + isReady = false; } GameLogic::IPlayerData* GameClient::GetPlayer() @@ -46,13 +45,26 @@ SmartPointer GameClient::ReleaseClient() this->client = 0; return temp; } -int GameClient::GetID() const + +float GameClient::GetSinceLastResponse() const { - return this->id; + return this->secondsSinceLastResponse; +} +bool GameClient::IsReady() const +{ + return this->isReady; } bool GameClient::Equals(const NetworkClient* c) { return (c->GetID() == this->client->GetID()); } +void GameClient::SetReadyState(bool r) +{ + this->isReady = r; +} +void GameClient::SetSinceLastResponse(float s) +{ + this->secondsSinceLastResponse = s; +} diff --git a/Code/Game/GameServer/Implementation/GameLobby.cpp b/Code/Game/GameServer/Implementation/GameLobby.cpp index b68846d4..b5fa8f40 100644 --- a/Code/Game/GameServer/Implementation/GameLobby.cpp +++ b/Code/Game/GameServer/Implementation/GameLobby.cpp @@ -17,18 +17,18 @@ namespace DanBias { } GameLobby::~GameLobby() - { } + { + this->clients.Clear(); + } void GameLobby::Release() { NetworkSession::CloseSession(true); + this->gameSession.CloseSession(true); } void GameLobby::Update() { - if(GetAsyncKeyState(VK_DOWN)) //TODO: Dont forget to remove this... - this->Send(*GameLogic::Protocol_General_Status().GetProtocol()); - this->ProcessClients(); } void GameLobby::SetGameDesc(const LobbyLevelData& desc) @@ -45,20 +45,21 @@ namespace DanBias desc.mapNumber = this->description.mapNumber; desc.maxClients = this->description.maxClients; } - bool GameLobby::StartGameSession() + bool GameLobby::StartGameSession( ) { GameSession::GameDescription desc; - desc.gameMode = this->description.gameMode; - desc.gameTime = this->description.gameTime; - desc.mapNumber = this->description.mapNumber; - desc.owner = this; - desc.clients = this->clients; + desc.gameMode = this->description.gameMode; + desc.gameTime = this->description.gameTime; + desc.mapNumber = this->description.mapNumber; + desc.owner = this; + desc.clients = this->clients; - this->clients.Clear(); + this->clients.Clear(); //Remove clients from lobby list if(this->gameSession.Create(desc)) { this->gameSession.Run(); + return true; } return false; @@ -85,29 +86,36 @@ namespace DanBias void GameLobby::ClientConnectedEvent(Utility::DynamicMemory::SmartPointer client) { printf("New client(%i) connected - %s \n", client->GetID(), client->GetIpAddress().c_str()); - Attach(client); - Protocol_LobbyClientData p1; - Protocol_LobbyGameData p2; - - for (unsigned int i = 0; i < this->clients.Size(); i++) + if(this->gameSession) { - if(this->clients[i]) - { - Protocol_LobbyClientData::PlayerData t; - t.id = this->clients[i]->GetID(); - t.ip = this->clients[i]->GetIpAddress(); - t.team = 0; - t.name = "DennisÄrKung"; - p1.list.Push(t); - } + this->gameSession.Attach(client); } - p2.majorVersion = 1; - p2.minorVersion = 0; - p2.mapName = "BetsMap"; + else + { + Attach(client); + Protocol_LobbyClientData p1; + Protocol_LobbyGameData p2; + + for (unsigned int i = 0; i < this->clients.Size(); i++) + { + if(this->clients[i]) + { + Protocol_LobbyClientData::PlayerData t; + t.id = this->clients[i]->GetID(); + t.ip = this->clients[i]->GetIpAddress(); + t.team = 0; + t.name = "Dennis är kung tycker Erik!"; + p1.list.Push(t); + } + } + p2.majorVersion = 1; + p2.minorVersion = 0; + p2.mapName = "Dennis är kung tycker Erik!"; - client->Send(p1.GetProtocol()); - client->Send(p2.GetProtocol()); + client->Send(p1.GetProtocol()); + client->Send(p2.GetProtocol()); + } } }//End namespace DanBias \ No newline at end of file diff --git a/Code/Game/GameServer/Implementation/GameLobby_ProtocolParser.cpp b/Code/Game/GameServer/Implementation/GameLobby_ProtocolParser.cpp index 3a86bc6b..93986650 100644 --- a/Code/Game/GameServer/Implementation/GameLobby_ProtocolParser.cpp +++ b/Code/Game/GameServer/Implementation/GameLobby_ProtocolParser.cpp @@ -62,7 +62,14 @@ void GameLobby::GeneralText(GameLogic::Protocol_General_Text& p, Oyster::Network //} void GameLobby::LobbyStartGame(GameLogic::Protocol_LobbyStartGame& p, Oyster::Network::NetworkClient* c) { - //TODO: Prio 1 + if(this->sessionOwner->GetClient()->GetID() == c->GetID()) + { + + } + else + { + //Someone else tried to start the server.. + } } //void GameLobby::LobbyJoin(GameLogic::Protocol_LobbyJoin& p, Oyster::Network::NetworkClient* c) //{ diff --git a/Code/Game/GameServer/Implementation/GameServer.cpp b/Code/Game/GameServer/Implementation/GameServer.cpp index 416503e5..bb046a41 100644 --- a/Code/Game/GameServer/Implementation/GameServer.cpp +++ b/Code/Game/GameServer/Implementation/GameServer.cpp @@ -53,6 +53,7 @@ void GameServerAPI::ServerStart() } void GameServerAPI::ServerStop() { + if(!server.IsRunning()) return; lobby.Release(); server.Shutdown(); @@ -61,19 +62,19 @@ void GameServerAPI::ServerStop() int time = (int)total; int hour, min, sec; - hour=time / 3600; - time=time % 3600; - min=time / 60; - time=time % 60; + hour = time / 3600; + time = time % 3600; + min = time / 60; + time = time % 60; sec = time; printf( "Server has been running for: %i:%i:%i - [hh:mm:ss] \n\n", hour, min, sec ); - printf( "Terminating in : "); - for (int i = 0; i < 3; i++) - { - printf( "%i ", 3-i ); - Sleep(1000); - } + //printf( "Terminating in : "); + //for (int i = 0; i < 3; i++) + //{ + // printf( "%i ", 3-i ); + // Sleep(1000); + //} printf( "\nServer terminated!" ); } void GameServerAPI::ServerUpdate() @@ -82,7 +83,6 @@ void GameServerAPI::ServerUpdate() lobby.Update(); } - GameServerAPI::GameServerInfo GameServerAPI::ServerGetInfo() { GameServerAPI::GameServerInfo i; @@ -90,6 +90,11 @@ GameServerAPI::GameServerInfo GameServerAPI::ServerGetInfo() i.listenPort = server.GetPort(); return i; } +bool GameServerAPI::ServerIsRunning() +{ + return server.IsRunning(); +} + void GameServerAPI::GameSetMapId(const int& val) { LobbyLevelData d; @@ -150,6 +155,11 @@ const char* GameServerAPI::GameGetGameName() } bool GameServerAPI::GameStart() { - return lobby.StartGameSession(); + if(lobby.StartGameSession()) + { + + return true; + } + return false; } diff --git a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp index beced0a4..b7d11e42 100644 --- a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp +++ b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp @@ -3,19 +3,16 @@ ///////////////////////////////////////////////////////////////////// #include "..\GameSession.h" #include "..\GameClient.h" +#include #include #include #include #include + #define NOMINMAX #include -#define DELTA_TIME_20 0.05f -#define DELTA_TIME_24 0.04166666666666666666666666666667f -#define DELTA_TIME_30 0.03333333333333333333333333333333f -#define DELTA_TIME_60 0.01666666666666666666666666666667f -#define DELTA_TIME_120 0.00833333333333333333333333333333f using namespace Utility::DynamicMemory; using namespace Oyster; @@ -25,20 +22,20 @@ using namespace GameLogic; namespace DanBias { + Utility::WinTimer testTimer; + int testID = -1; + bool GameSession::DoWork( ) { if(this->isRunning) { - double dt = this->timer.getElapsedSeconds(); - gameInstance.SetFrameTimeLength((float)dt); - - if(dt >= DELTA_TIME_20) + float dt = (float)this->logicTimer.getElapsedSeconds(); + if( dt >= this->logicFrameTime ) { this->ProcessClients(); - this->gameInstance.NewFrame(); - this->timer.reset(); + this->logicTimer.reset(); } } @@ -71,11 +68,16 @@ namespace DanBias case NetworkClient::ClientEventArgs::EventType_ProtocolFailedToRecieve: break; case NetworkClient::ClientEventArgs::EventType_ProtocolFailedToSend: - printf("\t(%i : %s) - EventType_ProtocolFailedToSend\n", e.sender->GetID(), e.sender->GetIpAddress().c_str()); - this->Detach(e.sender)->Disconnect(); + printf("\t(%i : %s) - EventType_ProtocolFailedToSend\n", cl->GetClient()->GetID(), e.sender->GetIpAddress().c_str()); + this->Detach(e.sender); break; case NetworkClient::ClientEventArgs::EventType_ProtocolRecieved: - printf("\t(%i : %s) - EventType_ProtocolRecieved\n", e.sender->GetID(), e.sender->GetIpAddress().c_str()); + printf("\t(%i : %s) - EventType_ProtocolRecieved\n", cl->GetClient()->GetID(), e.sender->GetIpAddress().c_str()); + testID = 2; + if(cl->GetPlayer()->GetID() == testID)//TODO: TEST + { + testTimer.reset(); + } this->ParseProtocol(e.args.data.protocol, cl); break; } @@ -83,38 +85,47 @@ namespace DanBias void GameSession::ObjectMove(GameLogic::IObjectData* movedObject) { - if(dynamic_cast (movedObject)) + float dt = GameSession::gameSession->networkTimer.getElapsedSeconds(); + //Duh... This was causing alot of problems, it's in the wrong place... + //Need to figure out where to put this frame locker. + //We only need to send network packages when necessary, ie not 120 times per frame. + //I think it would be enough with 60-70 packages per second due to the nature of + //graphics update (60 fps) on the client side. To send more than this would be lost + //bandwidth. + //if( dt >= GameSession::gameSession->networkFrameTime ) { - IPlayerData* temp = (IPlayerData*)movedObject; - - int id = temp->GetID(); - Oyster::Math::Float4x4 world = temp->GetOrientation(); - - Protocol_ObjectPosition p(world, id); - GameSession::gameSession->Send(*p.GetProtocol()); - } + GameSession::gameSession->networkTimer.reset(); - GameLogic::IObjectData* obj = NULL; - if(dynamic_cast(movedObject)) - { - obj = ((GameLogic::ILevelData*)movedObject)->GetObjectAt(0); - if(obj) + GameLogic::IObjectData* obj = movedObject; + if(movedObject->GetID() == testID) //TODO: TEST { - if(obj->GetObjectType() == OBJECT_TYPE_WORLD) - { - int id = obj->GetID(); - Oyster::Math::Float4x4 world =obj->GetOrientation(); - - Protocol_ObjectPosition p(world, id); - //GameSession::gameSession->Send(*p.GetProtocol()); - } + float sec = (float)testTimer.getElapsedSeconds(); + sec = 0; } - obj = NULL; - int count = ((GameLogic::ILevelData*)movedObject)->getNrOfDynamicObj(); - for( int i = 0; i < count; i++ ) + int id = obj->GetID(); + Protocol_ObjectPosition p(obj->GetOrientation(), id); + //if(id != 1) + GameSession::gameSession->Send(p.GetProtocol()); + + + /* + if(dynamic_cast(obj)) { - obj =((GameLogic::ILevelData*)movedObject)->GetObjectAt(i+1); + obj = ((GameLogic::ILevelData*)movedObject)->GetObjectAt(0); + if(obj) + { + if(obj->GetObjectType() == OBJECT_TYPE_WORLD) + { + int id = obj->GetID(); + Oyster::Math::Float4x4 world =obj->GetOrientation(); + + Protocol_ObjectPosition p(world, id); + gameSession->Send(p.GetProtocol()); + } + } + + obj =((GameLogic::ILevelData*)movedObject)->GetObjectAt(1); if(obj) { if(obj->GetObjectType() == OBJECT_TYPE_BOX) @@ -122,13 +133,30 @@ namespace DanBias int id = obj->GetID(); Oyster::Math::Float4x4 world = obj->GetOrientation(); Protocol_ObjectPosition p(world, id); - GameSession::gameSession->Send(*p.GetProtocol()); + gameSession->Send(p.GetProtocol()); + } + } + + obj =((GameLogic::ILevelData*)movedObject)->GetObjectAt(2); + if(obj) + { + if(obj->GetObjectType() == OBJECT_TYPE_BOX) + { + int id = obj->GetID(); + Oyster::Math::Float4x4 world = obj->GetOrientation(); + Protocol_ObjectPosition p(world, id); + GameSession::gameSession->Send(p.GetProtocol()); } } } + */ } } + void GameSession::ObjectDisabled( GameLogic::IObjectData* movedObject, float seconds ) + { + GameSession::gameSession->Send(Protocol_ObjectDisable(movedObject->GetID(), seconds).GetProtocol()); + } //*****************************************************// //****************** Protocol methods *****************// @@ -136,6 +164,8 @@ namespace DanBias void GameSession::ParseProtocol(Oyster::Network::CustomNetProtocol& p, DanBias::GameClient* c) { + //TODO: Update response timer + switch (p[0].value.netShort) { case protocol_Gameplay_PlayerMovement: this->Gameplay_PlayerMovement ( Protocol_PlayerMovement (p), c ); @@ -228,6 +258,8 @@ namespace DanBias { case GameLogic::Protocol_General_Status::States_disconected: printf("Client with ID [%i] dissconnected\n", c->GetClient()->GetID()); + //TODO: Tell other clients + //Protocol_ this->Detach(c->GetClient()->GetID()); break; @@ -236,7 +268,7 @@ namespace DanBias break; case GameLogic::Protocol_General_Status::States_ready: - + c->SetReadyState(true); break; case GameLogic::Protocol_General_Status::States_leave: @@ -246,7 +278,7 @@ namespace DanBias } void GameSession::General_Text ( Protocol_General_Text& p, DanBias::GameClient* c ) { - printf("Message recieved from (%i):\t %s\n", c->GetID(), p.text.c_str()); + printf("Message recieved from (%i):\t %s\n", c->GetClient()->GetID(), p.text.c_str()); } }//End namespace DanBias diff --git a/Code/Game/GameServer/Implementation/GameSession_General.cpp b/Code/Game/GameServer/Implementation/GameSession_General.cpp index ae947874..d6e6106c 100644 --- a/Code/Game/GameServer/Implementation/GameSession_General.cpp +++ b/Code/Game/GameServer/Implementation/GameSession_General.cpp @@ -9,6 +9,13 @@ #define NOMINMAX #include +#include + +#define DELTA_TIME_20 0.05f +#define DELTA_TIME_24 0.04166666666666666666666666666667f +#define DELTA_TIME_30 0.03333333333333333333333333333333f +#define DELTA_TIME_60 0.01666666666666666666666666666667f +#define DELTA_TIME_120 0.00833333333333333333333333333333f using namespace Utility::DynamicMemory; @@ -28,6 +35,10 @@ namespace DanBias this->isCreated = false; this->isRunning = false; this->gameSession = this; + this->logicFrameTime = DELTA_TIME_20; + this->networkFrameTime = DELTA_TIME_20; + this->networkTimer.reset(); + this->logicTimer.reset(); memset(&this->description, 0, sizeof(GameDescription)); } @@ -45,37 +56,30 @@ namespace DanBias bool GameSession::Create(GameDescription& desc) { this->description = desc; - /* Do some error checking */ + /* Do some error checking */ if(desc.clients.Size() == 0) return false; if(!desc.owner) return false; if(this->isCreated) return false; - /* standard initialization of some data */ + /* standard initialization of some data */ NetworkSession::clients = desc.clients; - this->clients.Resize(desc.clients.Size()); + this->clients.Reserve(desc.clients.Size()); this->owner = desc.owner; - /* Initiate the game instance */ + /* Initiate the game instance */ if(!this->gameInstance.Initiate()) { printf("Failed to initiate the game instance\n"); } - /* Create the game level */ - if(!(this->levelData = this->gameInstance.CreateLevel())) - { - printf("Level not created!"); - return false; - } - - /* Create the players in the game instance */ + /* Create the players in the game instance */ GameLogic::IPlayerData* p = 0; for (unsigned int i = 0; i < desc.clients.Size(); i++) { if( (p = this->gameInstance.CreatePlayer()) ) { desc.clients[i]->SetOwner(this); - this->clients[i] = new GameClient(desc.clients[i], p); + this->clients.Push(new GameClient(desc.clients[i], p)); } else { @@ -83,16 +87,26 @@ namespace DanBias } } + /* Create the game level */ + if(!(this->levelData = this->gameInstance.CreateLevel())) + { + printf("Level not created!"); + return false; + } + + /* Set some game instance data options */ + this->gameInstance.SetSubscription(GameSession::ObjectMove); + this->gameInstance.SetSubscription(GameSession::ObjectDisabled); + this->gameInstance.SetFPS(60); + + this->description.clients.Clear(); + + this->isCreated = true; + /* Create the worker thread */ if(this->worker.Create(this, false) != OYSTER_THREAD_ERROR_SUCCESS) return false; - this->worker.SetPriority(Oyster::Thread::OYSTER_THREAD_PRIORITY_3); - - /* Set some game instance data options */ - this->gameInstance.SetSubscription(GameLogic::GameEvent::ObjectEventFunctionType_OnMove, GameSession::ObjectMove); - - this->isCreated = true; return this->isCreated; } @@ -108,14 +122,71 @@ namespace DanBias } } + void GameSession::ThreadEntry( ) + { + //List with clients that we are waiting on.. + DynamicArray> readyList = this->clients; + //First we need to clean invalid clients, if any, and tell them to start loading game data + for (unsigned int i = 0; i < readyList.Size(); i++) + { + if(!readyList[i]) + { + readyList.Remove(i); + } + else + { + Protocol_LobbyCreateGame p(readyList[i]->GetPlayer()->GetID(), "char_white.dan", readyList[i]->GetPlayer()->GetOrientation()); + readyList[i]->GetClient()->Send(p); + } + } + + unsigned int readyCounter = readyList.Size(); + + //Sync with clients + while (readyCounter != 0) + { + this->ProcessClients(); + for (unsigned int i = 0; i < readyList.Size(); i++) + { + if(readyList[i] && readyList[i]->IsReady()) + { + //Need to send information about other players, to all players + for (unsigned int k = 0; k < this->clients.Size(); k++) + { + if((this->clients[k] && readyList[i]) && readyList[i]->GetClient()->GetID() != this->clients[k]->GetClient()->GetID()) + { + Protocol_ObjectCreate p(this->clients[k]->GetPlayer()->GetOrientation(), this->clients[k]->GetPlayer()->GetID(), "char_white.dan"); //The model name will be custom later.. + readyList[i]->GetClient()->Send(p); + } + } + + readyCounter-- ; + readyList[i] = 0; + } + } + Sleep(5); //TODO: This might not be needed here. + } + + for (unsigned int i = 0; i < this->clients.Size(); i++) + { + if(this->clients[i]) + { + this->clients[i]->GetClient()->Send(GameLogic::Protocol_LobbyStartGame(5)); + } + } + } bool GameSession::Attach(Utility::DynamicMemory::SmartPointer client) { if(!this->isCreated) return false; client->SetOwner(this); - SmartPointer obj = new GameClient(client, this->gameInstance.CreatePlayer()); + + IPlayerData* player = this->gameInstance.CreatePlayer(); + if(!player) return false; + + SmartPointer obj = new GameClient(client, player); for (unsigned int i = 0; i < clients.Size(); i++) { @@ -131,6 +202,13 @@ namespace DanBias return true; } + void GameSession::CloseSession( bool dissconnectClients ) + { + this->worker.Terminate(); + NetworkSession::CloseSession(true); + this->clients.Clear(); + } + }//End namespace DanBias diff --git a/Code/GamePhysics/PhysicsStructs-Impl.h b/Code/GamePhysics/PhysicsStructs-Impl.h index 928c5099..07ba0bb2 100644 --- a/Code/GamePhysics/PhysicsStructs-Impl.h +++ b/Code/GamePhysics/PhysicsStructs-Impl.h @@ -52,6 +52,7 @@ namespace Oyster { return ::Oyster::Math3D::ViewMatrix( this->quaternion, (this->centerPos + offset) ); } + } } } diff --git a/Code/GamePhysics/PhysicsStructs.h b/Code/GamePhysics/PhysicsStructs.h index d4ca7b99..5dc7d6f1 100644 --- a/Code/GamePhysics/PhysicsStructs.h +++ b/Code/GamePhysics/PhysicsStructs.h @@ -30,6 +30,7 @@ namespace Oyster ::Oyster::Math::Float4x4 GetOrientation() const; ::Oyster::Math::Float4x4 GetView() const; ::Oyster::Math::Float4x4 GetView( const ::Oyster::Math::Float3 &offset ) const; + void CustomBodyState::ApplyFriction( const ::Oyster::Math::Float3 &j); // Variables for state ::Oyster::Math::Float mass, restitutionCoeff, staticFrictionCoeff, dynamicFrictionCoeff; diff --git a/Code/Misc/DynamicArray.h b/Code/Misc/DynamicArray.h index 1db30719..8b4c98da 100644 --- a/Code/Misc/DynamicArray.h +++ b/Code/Misc/DynamicArray.h @@ -44,6 +44,11 @@ namespace Utility unsigned int Size() const; unsigned int Capacity() const; + bool IsEmpty() const; + + T* begin(); + T* end(); + private: void Expand(int elements = 0); @@ -112,7 +117,7 @@ namespace Utility template const T& DynamicArray::operator[](unsigned int index) const { - assert(index < this->size); + assert((int)index < this->size); return this->data[index]; } @@ -165,7 +170,7 @@ namespace Utility template void DynamicArray::Remove(unsigned int index) { - assert(index > this->size); + assert(index > (unsigned int) this->size); T* temp = new T[this->capacity - 1]; @@ -181,7 +186,8 @@ namespace Utility template void DynamicArray::Clear() { - delete [] this->data; + if(this->data) + delete [] this->data; this->data = 0; this->size = 0; @@ -227,6 +233,11 @@ namespace Utility return (unsigned int)this->capacity; } + template bool DynamicArray::IsEmpty() const + { + return (this->size == 0); + } + template void DynamicArray::Expand(int elements) { if(elements < 1) return; @@ -248,6 +259,18 @@ namespace Utility } } + template T* DynamicArray::begin() + { + if(this->size == 0) return 0; + return &this->data[0]; + } + + template T* DynamicArray::end() + { + if(this->size == 0) return 0; + return ((&this->data[this->size - 1]) + 1); + } + #pragma endregion } } diff --git a/Code/Misc/Misc.vcxproj b/Code/Misc/Misc.vcxproj index 6c3db1ec..2d9392a3 100644 --- a/Code/Misc/Misc.vcxproj +++ b/Code/Misc/Misc.vcxproj @@ -152,8 +152,10 @@ - true - true + false + false + false + false @@ -172,8 +174,10 @@ - true - true + false + false + false + false diff --git a/Code/Misc/Resource/ResourceManager.cpp b/Code/Misc/Resource/ResourceManager.cpp index b4195bb4..6f4b0360 100644 --- a/Code/Misc/Resource/ResourceManager.cpp +++ b/Code/Misc/Resource/ResourceManager.cpp @@ -108,7 +108,7 @@ void SaveResource( std::map& resources, ResourceDat } bool Release(std::map& resources, ResourceData* resource) { - if(resource->referenceCount.Decref() == 0) + if(resource->referenceCount.Decref() < 1) { const wchar_t* temp = FindResourceKey(resources, resource->resource); @@ -123,7 +123,7 @@ bool Release(std::map& resources, ResourceData* res resource->resource = 0; break; - case Oyster::Resource::ResourceType_UNKNOWN: + case Oyster::Resource::ResourceType_CUSTOM: resource->unloadFnc(resource->resource); resource->resource = 0; break; @@ -137,6 +137,13 @@ bool Release(std::map& resources, ResourceData* res } ResourceData* Load(/*Out*/ResourceData* targetMem, /*in*/const wchar_t source[], /*in*/ResourceType type) { + targetMem->resource = 0; + targetMem->loadFnc = 0; + targetMem->unloadFnc = 0; + targetMem->resourceID = 0; + targetMem->resourcetype = type; + targetMem->resourceSize = 0; + std::string sOut; bool success = false; @@ -182,13 +189,20 @@ ResourceData* Load(/*Out*/ResourceData* targetMem, /*in*/const wchar_t source[], } ResourceData* Load(/*Out*/ResourceData* targetMem, /*in*/const wchar_t source[], LoadFunction loadFnc, UnloadFunction unloadFnc) { + targetMem->resource = 0; + targetMem->loadFnc = 0; + targetMem->unloadFnc = 0; + targetMem->resourceID = 0; + targetMem->resourcetype = ResourceType_CUSTOM; + targetMem->resourceSize = 0; + if(loadFnc) { targetMem->resource = loadFnc(source); if(targetMem->resource) { targetMem->resourceSize = 0; - targetMem->resourcetype = ResourceType_UNKNOWN; + targetMem->resourcetype = ResourceType_CUSTOM; targetMem->loadFnc = loadFnc; targetMem->unloadFnc = unloadFnc; } @@ -208,7 +222,7 @@ ResourceData* Reload(std::map resources, ResourceDa return Load(resource, filename, resource->loadFnc, resource->unloadFnc); break; - case Oyster::Resource::ResourceType_UNKNOWN: + case Oyster::Resource::ResourceType_CUSTOM: { resource->unloadFnc(resource->resource); @@ -270,7 +284,7 @@ HRESOURCE ResourceManager::LoadResource(const wchar_t filename[], LoadFunction l { return 0; } - if(!loadFnc) + if(!loadFnc || !unloadFnc) { return 0; } @@ -278,6 +292,8 @@ HRESOURCE ResourceManager::LoadResource(const wchar_t filename[], LoadFunction l ResourceData *t = FindResource(this->resources, filename); if(t) { + t->loadFnc = loadFnc; + t->unloadFnc = unloadFnc; if(force) { return ResourceManager::ReloadResource(filename); @@ -292,7 +308,7 @@ HRESOURCE ResourceManager::LoadResource(const wchar_t filename[], LoadFunction l else { t = Load(new ResourceData(), filename, loadFnc, unloadFnc ); - if(t) + if(t && t->resource) { t->resourceID = (customId); SaveResource(this->resources, t, filename, true); @@ -300,6 +316,7 @@ HRESOURCE ResourceManager::LoadResource(const wchar_t filename[], LoadFunction l else { delete t; + t = 0; } } if(!t) @@ -333,24 +350,20 @@ void ResourceManager::Clean() for (i; i != last; i++) { //Remove all the references - while (!Release(this->resources, i->second)); + while (!Release(resources, i->second)); } resources.clear(); } void ResourceManager::ReleaseResource(const HRESOURCE& resourceData) { - ResourceData *t = FindResource(this->resources, resourceData); - if(t) + const wchar_t* temp = FindResourceKey(resources, resourceData); + + if(temp) { + ResourceData *t = FindResource(this->resources, resourceData); if(Release(resources, t)) { - const wchar_t* temp = 0; - if((temp = FindResourceKey(resources, resourceData))) - { - std::wstring ws = std::wstring(temp); - delete resources[ws]; - resources.erase(ws); - } + resources.erase(temp); } } } @@ -361,7 +374,6 @@ void ResourceManager::ReleaseResource(const wchar_t filename[]) { if(Release(resources, t)) { - delete resources[filename]; resources.erase(filename); } } diff --git a/Code/Misc/Resource/ResourceManager.h b/Code/Misc/Resource/ResourceManager.h index 4ab34b9b..4c90966e 100644 --- a/Code/Misc/Resource/ResourceManager.h +++ b/Code/Misc/Resource/ResourceManager.h @@ -29,10 +29,8 @@ namespace Oyster ResourceType_Byte_UNICODE, /**< Handle can be interpeted as char[] or char* */ ResourceType_Byte_UTF16LE, /**< Handle can be interpeted as char[] or char* */ - ResourceType_COUNT, /**< Handle can be interpeted as ? */ - - ResourceType_UNKNOWN = -1, /**< Handle can be interpeted as void* */ - ResourceType_INVALID = -2, /**< Invalid or non existing resource */ + ResourceType_CUSTOM, /**< Handle can be interpeted as whatever */ + ResourceType_INVALID, /**< Handle can be interpeted as whatever */ }; /** A resource handler interface to interact with when loading resources. diff --git a/Code/Misc/Thread/OysterThread_Impl.cpp b/Code/Misc/Thread/OysterThread_Impl.cpp index 79c7c700..91430eab 100644 --- a/Code/Misc/Thread/OysterThread_Impl.cpp +++ b/Code/Misc/Thread/OysterThread_Impl.cpp @@ -42,15 +42,10 @@ using namespace Utility::DynamicMemory; }; struct ThreadData { - OYSTER_THREAD_STATE state; // ownerObj; // - OwnerContainer ownerObj; // - std::atomic msec; //threadData->state = OYSTER_THREAD_STATE_DEAD; - - if(this->workerThread.joinable()) + if(std::this_thread::get_id() != this->workerThread.get_id()) { - this->workerThread.join(); + //this->threadData->threadDataAcces.lock(); + //{ + this->threadData->state = OYSTER_THREAD_STATE_DEAD; + + if(this->workerThread.joinable()) + { + this->workerThread.join(); + } + + this->isCreated = false; + delete this->threadData; + this->threadData = 0; + //} this->threadData->threadDataAcces.unlock(); + } + else + { + this->threadData->state = OYSTER_THREAD_STATE_DEAD; + if(this->workerThread.joinable()) + { + this->workerThread.join(); + } + this->isCreated = false; delete this->threadData; this->threadData = 0; @@ -102,12 +115,10 @@ using namespace Utility::DynamicMemory; this->threadData->state = OYSTER_THREAD_STATE_IDLE; threadData->ownerObj = worker; threadData->prio = OYSTER_THREAD_PRIORITY_2; + threadData->msec = 0; workerThread = std::thread(fnc, this->threadData); - //if(detach) - // this->workerThread.detach(); - isCreated = true; return OYSTER_THREAD_ERROR_SUCCESS; @@ -145,6 +156,9 @@ using namespace Utility::DynamicMemory; public: static void CheckPriority(ThreadData* w) { + + Oyster::Thread::OYSTER_THREAD_PRIORITY temp = w->prio; + switch (w->prio) { case Oyster::Thread::OYSTER_THREAD_PRIORITY_1: @@ -190,16 +204,18 @@ using namespace Utility::DynamicMemory; while (w->state == OYSTER_THREAD_STATE_NORMAL) { - CheckPriority(w); - if(!DoWork(w)) break; - CheckStatus(w); + //while (!w->threadDataAcces.try_lock()); + + CheckPriority(w); + if(!DoWork(w)) break; + CheckStatus(w); + + //w->threadDataAcces.unlock(); } if(w->ownerObj.value.obj) w->ownerObj.value.obj->ThreadExit(); w->state = OYSTER_THREAD_STATE_DEAD; - - //delete w; } }; @@ -247,79 +263,114 @@ OYSTER_THREAD_ERROR OysterThread::Create(ThreadFnc worker, bool start, bool deta OYSTER_THREAD_ERROR OysterThread::Start() { - if(!this->privateData->data->threadData->ownerObj) - return OYSTER_THREAD_ERROR_ThreadHasNoWorker; + OYSTER_THREAD_ERROR val = OYSTER_THREAD_ERROR_SUCCESS; + //this->privateData->data->threadData->threadDataAcces.lock();{ - if(this->privateData->data->threadData->state == OYSTER_THREAD_STATE_DEAD) - return OYSTER_THREAD_ERROR_ThreadIsDead; + if(!this->privateData->data->threadData->ownerObj) + val = OYSTER_THREAD_ERROR_ThreadHasNoWorker; - this->privateData->data->threadData->state = OYSTER_THREAD_STATE_NORMAL; + if(this->privateData->data->threadData->state == OYSTER_THREAD_STATE_DEAD) + val = OYSTER_THREAD_ERROR_ThreadIsDead; - return OYSTER_THREAD_ERROR_SUCCESS; + this->privateData->data->threadData->state = OYSTER_THREAD_STATE_NORMAL; + + //} this->privateData->data->threadData->threadDataAcces.unlock(); + + return val; } OYSTER_THREAD_ERROR OysterThread::Stop() { - this->privateData->data->threadData->state = OYSTER_THREAD_STATE_IDLE; - return OYSTER_THREAD_ERROR_SUCCESS; + OYSTER_THREAD_ERROR val = OYSTER_THREAD_ERROR_SUCCESS; + //this->privateData->data->threadData->threadDataAcces.lock(); { + this->privateData->data->threadData->state = OYSTER_THREAD_STATE_IDLE; + //} this->privateData->data->threadData->threadDataAcces.unlock(); + + return val; } OYSTER_THREAD_ERROR OysterThread::Stop(int msec) { - this->privateData->data->threadData->msec = msec; - return OYSTER_THREAD_ERROR_SUCCESS; + OYSTER_THREAD_ERROR val = OYSTER_THREAD_ERROR_SUCCESS; + //this->privateData->data->threadData->threadDataAcces.lock(); { + this->privateData->data->threadData->msec = msec; + //} this->privateData->data->threadData->threadDataAcces.unlock(); + return val; } OYSTER_THREAD_ERROR OysterThread::Resume() { - if(this->privateData->data->threadData->state == OYSTER_THREAD_STATE_DEAD) - return OYSTER_THREAD_ERROR_ThreadIsDead; + OYSTER_THREAD_ERROR val = OYSTER_THREAD_ERROR_SUCCESS; + //this->privateData->data->threadData->threadDataAcces.lock(); { + if(this->privateData->data->threadData->state == OYSTER_THREAD_STATE_DEAD) + val = OYSTER_THREAD_ERROR_ThreadIsDead; - this->privateData->data->threadData->state = OYSTER_THREAD_STATE_NORMAL; + this->privateData->data->threadData->state = OYSTER_THREAD_STATE_NORMAL; + //} this->privateData->data->threadData->threadDataAcces.unlock(); - return OYSTER_THREAD_ERROR_SUCCESS; + return val; } OYSTER_THREAD_ERROR OysterThread::SetWorker(IThreadObject* worker) { - this->privateData->data->threadData->ownerObj.value = worker; - this->privateData->data->threadData->ownerObj.type = Oyster::Callback::CallbackType_Object; + OYSTER_THREAD_ERROR val = OYSTER_THREAD_ERROR_SUCCESS; + //this->privateData->data->threadData->threadDataAcces.lock();{ - this->privateData->data->threadData->msec = 0; + this->privateData->data->threadData->ownerObj.value = worker; + this->privateData->data->threadData->ownerObj.type = Oyster::Callback::CallbackType_Object; - return OYSTER_THREAD_ERROR_SUCCESS;; + this->privateData->data->threadData->msec = 0; + //} this->privateData->data->threadData->threadDataAcces.unlock(); + + return val;; } OYSTER_THREAD_ERROR OysterThread::SetWorker(ThreadFnc worker) { - this->privateData->data->threadData->ownerObj.value = worker; - this->privateData->data->threadData->ownerObj.type = Oyster::Callback::CallbackType_Function; + OYSTER_THREAD_ERROR val = OYSTER_THREAD_ERROR_SUCCESS; + //this->privateData->data->threadData->threadDataAcces.lock();{ - this->privateData->data->threadData->msec = 0; + this->privateData->data->threadData->ownerObj.value = worker; + this->privateData->data->threadData->ownerObj.type = Oyster::Callback::CallbackType_Function; - return OYSTER_THREAD_ERROR_SUCCESS;; + this->privateData->data->threadData->msec = 0; + //} this->privateData->data->threadData->threadDataAcces.unlock(); + + return val;; } OYSTER_THREAD_ERROR OysterThread::Terminate() { if(this->privateData) return this->privateData->Terminate(); + return OYSTER_THREAD_ERROR_SUCCESS; } OYSTER_THREAD_ERROR OysterThread::Wait() { - if(this->privateData->data->threadData->state == OYSTER_THREAD_STATE_DEAD) - return OYSTER_THREAD_ERROR_ThreadIsDead; + OYSTER_THREAD_ERROR val = OYSTER_THREAD_ERROR_SUCCESS; - if( this->privateData->data->workerThread.get_id() == std::this_thread::get_id()) - return OYSTER_THREAD_ERROR_ThreadCannotWaintOnItselfe; + //this->privateData->data->threadData->threadDataAcces.lock();{ - return OYSTER_THREAD_ERROR_SUCCESS; + if(this->privateData->data->threadData->state == OYSTER_THREAD_STATE_DEAD) + val = OYSTER_THREAD_ERROR_ThreadIsDead; + + if( this->privateData->data->workerThread.get_id() == std::this_thread::get_id()) + val = OYSTER_THREAD_ERROR_ThreadCannotWaintOnItselfe; + + //} this->privateData->data->threadData->threadDataAcces.unlock(); + + return val; } OYSTER_THREAD_ERROR OysterThread::Wait(int msec) { - if(this->privateData->data->workerThread.get_id() == std::this_thread::get_id()) - return OYSTER_THREAD_ERROR_ThreadCannotWaintOnItselfe; - - return OYSTER_THREAD_ERROR_SUCCESS; + OYSTER_THREAD_ERROR val = OYSTER_THREAD_ERROR_SUCCESS; + + //this->privateData->data->threadData->threadDataAcces.lock();{ + if(this->privateData->data->workerThread.get_id() == std::this_thread::get_id()) + val = OYSTER_THREAD_ERROR_ThreadCannotWaintOnItselfe; + //} this->privateData->data->threadData->threadDataAcces.unlock(); + return val; } OYSTER_THREAD_ERROR OysterThread::Swap(const OysterThread* other) { - this->privateData->data->workerThread.swap(other->privateData->data->workerThread); + //this->privateData->data->threadData->threadDataAcces.lock();{ + this->privateData->data->workerThread.swap(other->privateData->data->workerThread); + //} this->privateData->data->threadData->threadDataAcces.unlock(); return OYSTER_THREAD_ERROR_SUCCESS; } diff --git a/Code/Misc/ThreadSafeQueue.h b/Code/Misc/ThreadSafeQueue.h index 3afb1cb3..eaed9516 100644 --- a/Code/Misc/ThreadSafeQueue.h +++ b/Code/Misc/ThreadSafeQueue.h @@ -34,12 +34,15 @@ namespace Utility virtual bool IsEmpty(); virtual void Swap( IQueue &queue ); + virtual void Clear(); + private: class Node { public: Type item; Node *next; + Node(){ this->next = NULL; }; Node(Type item){ this->item = item; this->next = NULL; }; ~Node() {}; }; @@ -215,6 +218,15 @@ namespace Utility stdMutex.unlock(); } + template < typename Type > + void ThreadSafeQueue::Clear() + { + while (!IsEmpty()) + { + Pop(); + } + } + } } diff --git a/Code/Misc/Utilities-Impl.h b/Code/Misc/Utilities-Impl.h index 1cfe8b8f..eedf9430 100644 --- a/Code/Misc/Utilities-Impl.h +++ b/Code/Misc/Utilities-Impl.h @@ -374,7 +374,191 @@ namespace Utility return (this->_ptr != NULL) ? true : false; } #pragma endregion - + + } + + namespace Thread + { +#pragma region ThreadSafeSmartPointer + template void ThreadSafeSmartPointer::Destroy() + { + delete this->_rc.load(); + this->_rc = NULL; + + //Use default function for memory deallocation. + SafeDeleteInstance(this->_ptr.load()); + + this->_ptr = NULL; + } + template ThreadSafeSmartPointer::ThreadSafeSmartPointer() + :_rc(0), _ptr(0) + { } + template ThreadSafeSmartPointer::ThreadSafeSmartPointer(UniquePointer& p) + :_ptr(p.Release()) + { + this->_rc = new ReferenceCount(); + this->_rc->Incref(); + } + template ThreadSafeSmartPointer::ThreadSafeSmartPointer(T* p) + :_ptr(p) + { + this->_rc.store = new ReferenceCount(); + this->_rc->Incref(); + } + template ThreadSafeSmartPointer::ThreadSafeSmartPointer(const ThreadSafeSmartPointer& d) + :_ptr(d._ptr), _rc(d._rc) + { + if(this->_rc) + this->_rc->Incref(); + } + template ThreadSafeSmartPointer::~ThreadSafeSmartPointer() + { + this->Release(); + } + template ThreadSafeSmartPointer& ThreadSafeSmartPointer::operator= (const ThreadSafeSmartPointer& p) + { + if (this != &p) + { + //Last to go? + if(this->_rc.load() && this->_rc.load()->Decref() == 0) + { + //Call child specific + Destroy(); + } + + this->_ptr.store(p._ptr.load()); + this->_rc.store(p._rc.load()); + if(this->_rc.load()) this->_rc.load()->Incref(); + } + return *this; + } + template ThreadSafeSmartPointer& ThreadSafeSmartPointer::operator= (UniquePointer& p) + { + //Last to go? + if(this->_rc) + { + if(this->_rc->Decref() == 0) + { + //Call child specific + Destroy(); + this->_rc = new ReferenceCount(); + } + } + else + { + if(p) this->_rc = new ReferenceCount(); + } + + if(this->_rc) + this->_rc->Incref(); + + this->_ptr = p.Release(); + + return *this; + } + template ThreadSafeSmartPointer& ThreadSafeSmartPointer::operator= (T* p) + { + if (this->_ptr != p) + { + //Last to go? + if(this->_rc.load()) + { + if(this->_rc.load()->Decref() == 0) + { + //Call child specific + Destroy(); + if(p) this->_rc = new ReferenceCount(); + } + } + else if(p) + { + this->_rc = new ReferenceCount(); + } + + this->_ptr = p; + + if(p) this->_rc.load()->Incref(); + else this->_rc = 0; + } + return *this; + } + template inline bool ThreadSafeSmartPointer::operator== (const ThreadSafeSmartPointer& d) const + { + return d._ptr == this->_ptr; + } + template inline bool ThreadSafeSmartPointer::operator== (const T& p) const + { + return &p == this->_ptr; + } + template inline bool ThreadSafeSmartPointer::operator!= (const ThreadSafeSmartPointer& d) const + { + return d._ptr != this->_ptr; + } + template inline bool ThreadSafeSmartPointer::operator!= (const T& p) const + { + return &p != this->_ptr; + } + template inline T& ThreadSafeSmartPointer::operator* () + { + return *this->_ptr; + } + template inline const T& ThreadSafeSmartPointer::operator* () const + { + return *this->_ptr; + } + template inline T* ThreadSafeSmartPointer::operator-> () + { + return this->_ptr; + } + template inline const T* ThreadSafeSmartPointer::operator-> () const + { + return this->_ptr; + } + template inline ThreadSafeSmartPointer::operator T* () const + { + return this->_ptr; + } + template inline ThreadSafeSmartPointer::operator const T* () const + { + return this->_ptr; + } + template inline ThreadSafeSmartPointer::operator T& () const + { + return *this->_ptr; + } + template inline ThreadSafeSmartPointer::operator bool() const + { + return (this->_ptr != 0); + } + template inline T* ThreadSafeSmartPointer::Get() + { + return this->_ptr; + } + template inline T* ThreadSafeSmartPointer::Get() const + { + return this->_ptr; + } + template int ThreadSafeSmartPointer::Release() + { + int returnVal = 0; + + if(this->_rc.load() && ((returnVal = this->_rc.load()->Decref()) == 0)) + { + Destroy(); + } + return returnVal; + } + template int ThreadSafeSmartPointer::ReleaseDummy() + { + int val = this->_rc->Decref(); + this->_rc->Incref(); + return val; + } + template inline bool ThreadSafeSmartPointer::IsValid() const + { + return (this->_ptr != NULL) ? true : false; + } +#pragma endregion } } diff --git a/Code/Misc/Utilities.cpp b/Code/Misc/Utilities.cpp index cdf3d136..7f6a3302 100644 --- a/Code/Misc/Utilities.cpp +++ b/Code/Misc/Utilities.cpp @@ -300,7 +300,7 @@ namespace Utility //To wstring - ::std::wstring & StringToWString( const ::std::string &str, ::std::wstring &wstr ) + ::std::wstring & StringToWstring( const ::std::string &str, ::std::wstring &wstr ) { const char *orig = str.c_str(); diff --git a/Code/Misc/Utilities.h b/Code/Misc/Utilities.h index 9b3abac0..c259a845 100644 --- a/Code/Misc/Utilities.h +++ b/Code/Misc/Utilities.h @@ -408,7 +408,59 @@ namespace Utility namespace Thread { - //Utilities for threading + using namespace DynamicMemory; + //! Wrapper to manage references on a pointer. + template struct ThreadSafeSmartPointer + { + private: + std::atomic _rc; + std::atomic _ptr; + + /** Destroys the pointer and returns the memory allocated. */ + void Destroy(); + + public: + ThreadSafeSmartPointer(); + ThreadSafeSmartPointer(UniquePointer& up); + ThreadSafeSmartPointer(T* p); + ThreadSafeSmartPointer(const ThreadSafeSmartPointer& d); + virtual~ThreadSafeSmartPointer(); + ThreadSafeSmartPointer& operator= (const ThreadSafeSmartPointer& p); + ThreadSafeSmartPointer& operator= (UniquePointer& p); + ThreadSafeSmartPointer& operator= (T* p); + bool operator== (const ThreadSafeSmartPointer& d) const; + bool operator== (const T& p) const; + bool operator!= (const ThreadSafeSmartPointer& d) const; + bool operator!= (const T& p) const; + T& operator* (); + const T& operator* () const; + T* operator-> (); + const T* operator-> () const; + operator T* () const; + operator const T* () const; + operator T& () const; + operator bool() const; + + /** + * Returns the connected pointer + */ + T* Get(); + T* Get() const; + + /** + * Releases one reference of the pointer and set value to null, making the current ThreadSafeSmartPointer invalid. + */ + int Release(); + /** + * Only test to release to check reference count. + */ + int ReleaseDummy(); + + /** Checks if the pointer is valid (not NULL) + * Returns true for valid, else false. + */ + bool IsValid() const; + }; } } diff --git a/Code/Network/NetworkAPI/CustomNetProtocol.cpp b/Code/Network/NetworkAPI/CustomNetProtocol.cpp index 2ac6fcf5..ecb57bf9 100644 --- a/Code/Network/NetworkAPI/CustomNetProtocol.cpp +++ b/Code/Network/NetworkAPI/CustomNetProtocol.cpp @@ -4,42 +4,31 @@ #include "CustomNetProtocol.h" #include #include "Translator.h" -#include "Utilities.h" +#include using namespace Oyster::Network; using namespace Utility::DynamicMemory; struct CustomNetProtocol::PrivateData { - std::map attributes; //...Im an idiot - Utility::DynamicMemory::ReferenceCount *c; - + //std::map attributes; //...Im an idiot + DynamicArray attributes; //...Im an idiot + PrivateData() - { - //this->attributes = new std::map(); - this->c = new ReferenceCount(); - c->Incref(); - } + { } ~PrivateData() { - delete c; - c = 0; - for (auto i = attributes.begin(); i != attributes.end(); i++) - { - RemoveAttribute(i->first); - } - attributes.clear(); + attributes.Clear(); } - void RemoveAttribute(int ID) + void RemoveAttribute(NetAttributeContainer* i) { - auto i = attributes.find(ID); - if(i == attributes.end()) return; + if(!i) return; - switch (i->second.type) + switch (i->type) { case NetAttributeType_CharArray: - delete [] i->second.value.netCharPtr; + delete [] i->value.netCharPtr; break; } } @@ -47,55 +36,42 @@ struct CustomNetProtocol::PrivateData //Do network stuff }; - CustomNetProtocol::CustomNetProtocol() { this->privateData = new PrivateData(); } -CustomNetProtocol::CustomNetProtocol(const CustomNetProtocol& o) +CustomNetProtocol::CustomNetProtocol(CustomNetProtocol& o) { - this->privateData = o.privateData; - if(this->privateData) - { - this->privateData->c = o.privateData->c; - this->privateData->c->Incref(); - } + this->privateData = new PrivateData(); + this->privateData->attributes = o.privateData->attributes; } -const CustomNetProtocol& CustomNetProtocol::operator=(const CustomNetProtocol& o) +const CustomNetProtocol& CustomNetProtocol::operator=(CustomNetProtocol& o) { - if(this->privateData && this->privateData->c) + if(this->privateData) { - if(this->privateData->c->Decref() == 0) - { - delete this->privateData; - } - } - - this->privateData = o.privateData; - if(this->privateData) - { - this->privateData->c = o.privateData->c; - this->privateData->c->Incref(); + delete this->privateData; + this->privateData = 0; } + this->privateData = new PrivateData(); + this->privateData->attributes = o.privateData->attributes; return *this; } CustomNetProtocol::~CustomNetProtocol() { - if(this->privateData && this->privateData->c) - { - if(this->privateData->c->Decref() == 0) - { - delete this->privateData; - } - } + delete this->privateData; + this->privateData = 0; } NetAttributeContainer& CustomNetProtocol::operator[](int ID) { - if(this->privateData->attributes.find(ID) == this->privateData->attributes.end()) + //if(!this->privateData) this->privateData = new PrivateData(); + if((unsigned int)ID >= this->privateData->attributes.Size()) { - this->privateData->attributes[ID]; - this->privateData->attributes[ID].type = NetAttributeType_UNKNOWN; - memset(&this->privateData->attributes[ID].value, 0, sizeof(NetAttributeValue)); + NetAttributeContainer temp; + + temp.type = NetAttributeType_UNKNOWN; + memset(&temp.value, 0, sizeof(NetAttributeValue)); + + this->privateData->attributes.Push(ID, temp); } return this->privateData->attributes[ID]; @@ -134,4 +110,115 @@ void CustomNetProtocol::Set(int ID, std::string s) const NetAttributeContainer& CustomNetProtocol::Get(int id) { return this->privateData->attributes[id]; -} \ No newline at end of file +} + + + + + +/////////////////////////////////////////////////////////////////////// +//// Created by [Dennis Andersen] [2013] +/////////////////////////////////////////////////////////////////////// +//#include "CustomNetProtocol.h" +//#include +//#include "Translator.h" +//#include +//using namespace Oyster::Network; +//using namespace Utility::DynamicMemory; +// +// +// +//struct CustomNetProtocol::PrivateData +//{ +// Utility::DynamicMemory::DynamicArray attributes; //...Im an idiot +// +// PrivateData() +// { } +// +// ~PrivateData() +// { +// for (unsigned int i = 0; i < attributes.Size(); i++) +// { +// RemoveAttribute(i); +// } +// +// attributes.Clear(); +// } +// void RemoveAttribute(int i) +// { +// switch (attributes[i].type) +// { +// case NetAttributeType_CharArray: +// delete [] attributes[i].value.netCharPtr; +// break; +// } +// } +// +// //Do network stuff +//}; +// +// +//CustomNetProtocol::CustomNetProtocol() +//{ +// this->privateData = new PrivateData(); +//} +//CustomNetProtocol::CustomNetProtocol(const CustomNetProtocol& o) +//{ +// this->privateData = o.privateData; +//} +//const CustomNetProtocol& CustomNetProtocol::operator=(const CustomNetProtocol& o) +//{ +// this->privateData = o.privateData; +// return *this; +//} +//CustomNetProtocol::~CustomNetProtocol() +//{ +//} +//NetAttributeContainer& CustomNetProtocol::operator[](int ID) +//{ +// if(ID >= this->privateData->attributes.Size()) +// this->privateData->attributes.Resize( +// if(this->privateData->attributes.find(ID) == this->privateData->attributes.end()) +// { +// this->privateData->attributes[ID]; +// this->privateData->attributes[ID].type = NetAttributeType_UNKNOWN; +// memset(&this->privateData->attributes[ID].value, 0, sizeof(NetAttributeValue)); +// } +// +// return this->privateData->attributes[ID]; +//} +// +//void CustomNetProtocol::Set(int ID, Oyster::Network::NetAttributeValue val, Oyster::Network::NetAttributeType type) +//{ +// this->privateData->attributes[ID].type = type; +// +// switch (type) +// { +// case Oyster::Network::NetAttributeType_Bool: +// case Oyster::Network::NetAttributeType_Char: +// case Oyster::Network::NetAttributeType_UnsignedChar: +// case Oyster::Network::NetAttributeType_Short: +// case Oyster::Network::NetAttributeType_UnsignedShort: +// case Oyster::Network::NetAttributeType_Int: +// case Oyster::Network::NetAttributeType_UnsignedInt: +// case Oyster::Network::NetAttributeType_Int64: +// case Oyster::Network::NetAttributeType_UnsignedInt64: +// case Oyster::Network::NetAttributeType_Float: +// case Oyster::Network::NetAttributeType_Double: +// this->privateData->attributes[ID].value = val; +// break; +// } +//} +//void CustomNetProtocol::Set(int ID, std::string s) +//{ +// if(s.size() == 0) return; +// +// this->privateData->attributes[ID].type = Oyster::Network::NetAttributeType_CharArray; +// +// this->privateData->attributes[ID].value.netCharPtr = new char[s.size() + 1]; +// memcpy(&this->privateData->attributes[ID].value.netCharPtr[0], &s[0], s.size() + 1); +//} +//const NetAttributeContainer& CustomNetProtocol::Get(int id) +//{ +// return this->privateData->attributes[id]; +//} \ No newline at end of file diff --git a/Code/Network/NetworkAPI/CustomNetProtocol.h b/Code/Network/NetworkAPI/CustomNetProtocol.h index 8e531f17..c982bd1f 100644 --- a/Code/Network/NetworkAPI/CustomNetProtocol.h +++ b/Code/Network/NetworkAPI/CustomNetProtocol.h @@ -4,7 +4,11 @@ #ifndef NETWORK_CUSTOM_NETWORK_PROTOCOL_H #define NETWORK_CUSTOM_NETWORK_PROTOCOL_H +//needs to have dll-interface to be used by clients of class 'Oyster::Network::NetworkSession' +#pragma warning(disable : 4251) + #include +#include "Utilities.h" //#include #include "NetworkAPI_Preprocessor.h" @@ -65,12 +69,60 @@ namespace Oyster { NetAttributeType type; NetAttributeValue value; - NetAttributeContainer() { type = NetAttributeType_UNKNOWN; } + NetAttributeContainer() + { type = NetAttributeType_UNKNOWN; } + ~NetAttributeContainer() + { + if (this->type == NetAttributeType_CharArray) + { + delete this->value.netCharPtr; + this->value.netCharPtr = 0; + } + } + NetAttributeContainer(NetAttributeContainer& p) + { + type = p.type; + if(type == NetAttributeType_CharArray && p.value.netCharPtr) + { + int len = 0; + if((len = strlen(p.value.netCharPtr)) == 0) return; + len++; + value.netCharPtr = new char[len]; + memcpy(&value.netCharPtr[0], &p.value.netCharPtr[0], sizeof(p.value.netCharPtr[0]) * len); + } + else + { + value = p.value; + } + } + const NetAttributeContainer& operator=(const NetAttributeContainer& p) + { + if(this->type == NetAttributeType_CharArray) + { + delete this->value.netCharPtr; + this->value.netCharPtr = 0; + } + + type = p.type; + if(type == NetAttributeType_CharArray && p.value.netCharPtr) + { + int len = 0; + if((len = strlen(p.value.netCharPtr)) == 0) return *this; + len++; + value.netCharPtr = new char[len]; + memcpy(&value.netCharPtr[0], &p.value.netCharPtr[0], sizeof(p.value.netCharPtr[0]) * len); + } + else + { + value = p.value; + } + return *this; + } }; class CustomNetProtocol; struct CustomProtocolObject { - virtual CustomNetProtocol* GetProtocol() = 0; + virtual CustomNetProtocol GetProtocol() = 0; }; class NET_API_EXPORT CustomNetProtocol @@ -78,8 +130,8 @@ namespace Oyster public: CustomNetProtocol(); ~CustomNetProtocol(); - CustomNetProtocol(const CustomNetProtocol& o); - const CustomNetProtocol& operator=(const CustomNetProtocol& o); + CustomNetProtocol(CustomNetProtocol& o); + const CustomNetProtocol& operator=(CustomNetProtocol& o); NetAttributeContainer& operator[](int ID); void Set(int id, Oyster::Network::NetAttributeValue val, Oyster::Network::NetAttributeType type); @@ -88,6 +140,8 @@ namespace Oyster private: struct PrivateData; + //Utility::DynamicMemory::SmartPointer privateData; + //Utility::Thread::ThreadSafeSmartPointer privateData; PrivateData* privateData; friend class Translator; diff --git a/Code/Network/NetworkAPI/NetworkClient.cpp b/Code/Network/NetworkAPI/NetworkClient.cpp index 717a2946..01ba495e 100644 --- a/Code/Network/NetworkAPI/NetworkClient.cpp +++ b/Code/Network/NetworkAPI/NetworkClient.cpp @@ -19,6 +19,7 @@ #include "../../Misc/Packing/Packing.h" #include +#include using namespace Oyster::Network; using namespace Oyster::Thread; @@ -61,9 +62,10 @@ struct NetworkClient::PrivateData : public IThreadObject } ~PrivateData() { + this->thread.Terminate(); + ShutdownWinSock(); this->connection.Disconnect(); - this->thread.Terminate(); this->owner = 0; this->parent = 0; } @@ -83,12 +85,13 @@ struct NetworkClient::PrivateData : public IThreadObject if(!this->sendQueue.IsEmpty()) { - SmartPointer temp = new OysterByte(); + //printf("\t(%i)\n", this->sendQueue.Size()); + OysterByte temp; CustomNetProtocol p = this->sendQueue.Pop(); this->translator.Pack(temp, p); errorCode = this->connection.Send(temp); - if(errorCode != 0) + if(errorCode != 0 && errorCode != WSAEWOULDBLOCK) { CEA parg; parg.type = CEA::EventType_ProtocolFailedToSend; @@ -204,7 +207,11 @@ struct NetworkClient::PrivateData : public IThreadObject CEA parg; parg.type = CEA::EventType_ProtocolRecieved; parg.data.protocol = protocol; - NetEvent e = { this->parent, parg }; + NetEvent e; + e.sender = this->parent; + e.args.data.protocol = parg.data.protocol; + e.args.type = parg.type; + this->recieveQueue.Push(e); } } @@ -247,9 +254,6 @@ void NetworkClient::Update() this->DataRecieved(temp); - //--------- Deprecate --------- - this->NetworkCallback(temp.args.data.protocol); - //------------------------------ } } @@ -291,18 +295,23 @@ bool NetworkClient::Connect(unsigned short port, const char serverIP[]) void NetworkClient::Disconnect() { - privateData->connection.Disconnect(); + if(!privateData) return; + privateData->thread.Terminate(); + privateData->connection.Disconnect(); + this->privateData->sendQueue.Clear(); + this->privateData->recieveQueue.Clear(); + } void NetworkClient::Send(CustomProtocolObject& protocol) { - this->privateData->sendQueue.Push(*protocol.GetProtocol()); + this->privateData->sendQueue.Push(protocol.GetProtocol()); } -void NetworkClient::Send(CustomNetProtocol* protocol) +void NetworkClient::Send(CustomNetProtocol& protocol) { - this->privateData->sendQueue.Push(*protocol); + this->privateData->sendQueue.Push(protocol); } void NetworkClient::SetOwner(NetworkSession* owner) @@ -329,8 +338,8 @@ void NetworkClient::DataRecieved(NetEvent e) } } -void NetworkClient::NetworkCallback(Oyster::Network::CustomNetProtocol& p) -{} +//void NetworkClient::NetworkCallback(Oyster::Network::CustomNetProtocol& p) +//{} std::string NetworkClient::GetIpAddress() { diff --git a/Code/Network/NetworkAPI/NetworkClient.h b/Code/Network/NetworkAPI/NetworkClient.h index dfe247de..a19f74e4 100644 --- a/Code/Network/NetworkAPI/NetworkClient.h +++ b/Code/Network/NetworkAPI/NetworkClient.h @@ -36,7 +36,33 @@ namespace Oyster { struct { Oyster::Network::CustomNetProtocol protocol; }; void * nothing; + EventData(){} + EventData(Oyster::Network::CustomNetProtocol& o) + { + protocol = o; + } + const EventData& operator=(EventData& o) + { + protocol = o.protocol; + return *this; + } + const EventData& operator=(Oyster::Network::CustomNetProtocol& o) + { + protocol = o; return *this; + } } data; + ClientEventArgs(){} + ClientEventArgs(ClientEventArgs& o) + { + type = o.type; + data = o.data; + } + const ClientEventArgs& operator=(ClientEventArgs& o) + { + type = o.type; + data = o.data; + return *this; + } }; typedef void(*ClientEventFunction)(NetEvent e); @@ -75,7 +101,7 @@ namespace Oyster /** * */ - void Send(CustomNetProtocol* protocol); + void Send(CustomNetProtocol& protocol); /** * @@ -101,7 +127,7 @@ namespace Oyster * Do not use this furthermore, instead use void DataRecieved(NetEvent e); * @see DataRecieved */ - virtual void NetworkCallback(Oyster::Network::CustomNetProtocol& p); + //virtual void NetworkCallback(Oyster::Network::CustomNetProtocol& p); virtual std::string GetIpAddress(); diff --git a/Code/Network/NetworkAPI/NetworkServer.cpp b/Code/Network/NetworkAPI/NetworkServer.cpp index 4bdc4abf..e31efcde 100644 --- a/Code/Network/NetworkAPI/NetworkServer.cpp +++ b/Code/Network/NetworkAPI/NetworkServer.cpp @@ -261,7 +261,7 @@ NetworkSession const* NetworkServer::ReleaseMainSession() return temp; } -bool NetworkServer::IsStarted() const +bool NetworkServer::IsRunning() const { return this->privateData->isRunning; } diff --git a/Code/Network/NetworkAPI/NetworkServer.h b/Code/Network/NetworkAPI/NetworkServer.h index 1a6af478..1e3ddd21 100644 --- a/Code/Network/NetworkAPI/NetworkServer.h +++ b/Code/Network/NetworkAPI/NetworkServer.h @@ -77,7 +77,7 @@ namespace Oyster /** * */ - bool IsStarted() const; + bool IsRunning() const; /** * diff --git a/Code/Network/NetworkAPI/NetworkSession.cpp b/Code/Network/NetworkAPI/NetworkSession.cpp index c7bf15ba..3d7bbadc 100644 --- a/Code/Network/NetworkAPI/NetworkSession.cpp +++ b/Code/Network/NetworkAPI/NetworkSession.cpp @@ -26,7 +26,15 @@ struct NetworkSession::PrivateSessionData {} }; - +int FindClient(NetClientList& list, NetClient c) +{ + for (unsigned int i = 0; i < list.Size(); i++) + { + if(c == list[i]) + return i; + } + return -1; +} NetworkSession::NetworkSession() : data(new PrivateSessionData()) @@ -125,7 +133,7 @@ NetClient NetworkSession::Detach(const NetworkClient* client) for (unsigned int i = 0; i < this->clients.Size(); i++) { - if(this->clients[i] && this->clients[0]->GetID() == client->GetID()) + if(this->clients[i] && this->clients[i]->GetID() == client->GetID()) { val = this->clients[i]; this->clients[i] = 0; @@ -188,7 +196,7 @@ bool NetworkSession::Send(Oyster::Network::CustomNetProtocol& protocol) { if(this->clients[i]) { - this->clients[i]->Send(&protocol); + this->clients[i]->Send(protocol); returnValue = true; } } @@ -202,7 +210,7 @@ bool NetworkSession::Send(Oyster::Network::CustomNetProtocol& protocol, int ID) { if(this->clients[i] && this->clients[i]->GetID() == ID) { - this->clients[i]->Send(&protocol); + this->clients[i]->Send(protocol); return true; } } @@ -237,5 +245,8 @@ void NetworkSession::SetOwner(NetworkSession* owner) void NetworkSession::ClientConnectedEvent(NetClient client) { this->Attach(client); + + if(FindClient(this->clients, client) == -1) + NetworkSession::Attach(client); } diff --git a/Code/Network/NetworkAPI/Translator.cpp b/Code/Network/NetworkAPI/Translator.cpp index 9b855d47..3e460b54 100644 --- a/Code/Network/NetworkAPI/Translator.cpp +++ b/Code/Network/NetworkAPI/Translator.cpp @@ -8,17 +8,18 @@ #include "../../Misc/Utilities.h" #include "../NetworkDependencies/Messages/MessageHeader.h" #include "../NetworkDependencies/OysterByte.h" - +#include using namespace Oyster::Network; using namespace ::Messages; using namespace Utility::DynamicMemory; using namespace std; + +//TODO: Fix this uggly hack struct MyCastingStruct { - std::map attributes; - Utility::DynamicMemory::ReferenceCount *c; + Utility::DynamicMemory::DynamicArray attributes; }; // TODO: Check if the package has been packed correctly. @@ -43,7 +44,7 @@ struct Translator::PrivateData //Find all the data types for(; it != end; it++) { - headerString.push_back(it->second.type); + headerString.push_back(it->type); } message.PackShort(headerString.size(), bytes); @@ -68,40 +69,40 @@ struct Translator::PrivateData switch((int)headerString.at(i)) { case NetAttributeType_Bool: - message.PackBool(it->second.value.netBool, bytes); + message.PackBool(it->value.netBool, bytes); break; case NetAttributeType_Char: - message.PackChar(it->second.value.netChar, bytes); + message.PackChar(it->value.netChar, bytes); break; case NetAttributeType_UnsignedChar: - message.PackUnsignedChar(it->second.value.netUChar, bytes); + message.PackUnsignedChar(it->value.netUChar, bytes); break; case NetAttributeType_Short: - message.PackShort(it->second.value.netShort, bytes); + message.PackShort(it->value.netShort, bytes); break; case NetAttributeType_UnsignedShort: - message.PackUnsignedShort(it->second.value.netUShort, bytes); + message.PackUnsignedShort(it->value.netUShort, bytes); break; case NetAttributeType_Int: - message.PackInt(it->second.value.netInt, bytes); + message.PackInt(it->value.netInt, bytes); break; case NetAttributeType_UnsignedInt: - message.PackUnsignedInt(it->second.value.netUInt, bytes); + message.PackUnsignedInt(it->value.netUInt, bytes); break; case NetAttributeType_Int64: - message.PackInt64(it->second.value.netInt64, bytes); + message.PackInt64(it->value.netInt64, bytes); break; case NetAttributeType_UnsignedInt64: - message.PackUnsignedInt64(it->second.value.netUInt64, bytes); + message.PackUnsignedInt64(it->value.netUInt64, bytes); break; case NetAttributeType_Float: - message.PackFloat(it->second.value.netFloat, bytes); + message.PackFloat(it->value.netFloat, bytes); break; case NetAttributeType_Double: - message.PackDouble(it->second.value.netDouble, bytes); + message.PackDouble(it->value.netDouble, bytes); break; case NetAttributeType_CharArray: - message.PackStr(it->second.value.netCharPtr, bytes); + message.PackStr(it->value.netCharPtr, bytes); break; default: numberOfUnknownTypes++; @@ -215,6 +216,7 @@ const Translator& Translator::operator=(const Translator& obj) void Translator::Pack(OysterByte &bytes, CustomNetProtocol& protocol) { + privateData->headerString.clear(); privateData->PackHeader(bytes, protocol); diff --git a/Code/OysterGraphics/Core/Core.cpp b/Code/OysterGraphics/Core/Core.cpp index 9f7ce465..f2392f4c 100644 --- a/Code/OysterGraphics/Core/Core.cpp +++ b/Code/OysterGraphics/Core/Core.cpp @@ -15,6 +15,11 @@ IDXGISwapChain* Core::swapChain = NULL; std::stringstream Core::log; +Oyster::Resource::ResourceManager Core::loader; + +std::wstring Core::modelPath; +std::wstring Core::texturePath; + ID3D11RenderTargetView* Core::backBufferRTV = NULL; ID3D11UnorderedAccessView* Core::backBufferUAV = NULL; diff --git a/Code/OysterGraphics/Core/Core.h b/Code/OysterGraphics/Core/Core.h index 3e8ffdd6..050d54c5 100644 --- a/Code/OysterGraphics/Core/Core.h +++ b/Code/OysterGraphics/Core/Core.h @@ -7,6 +7,7 @@ #include "Dx11Includes.h" #include #include "OysterMath.h" +#include "../Misc/Resource/ResourceManager.h" //#include namespace Oyster @@ -25,6 +26,10 @@ namespace Oyster static std::stringstream log; + static Resource::ResourceManager loader; + + static std::wstring modelPath, texturePath; + //BackBufferRTV static ID3D11RenderTargetView* backBufferRTV; //BackBufferUAV diff --git a/Code/OysterGraphics/Core/PipelineManager.cpp b/Code/OysterGraphics/Core/PipelineManager.cpp index c77873b5..d60c1641 100644 --- a/Code/OysterGraphics/Core/PipelineManager.cpp +++ b/Code/OysterGraphics/Core/PipelineManager.cpp @@ -2,7 +2,6 @@ #include #include #include "../FileLoader/GeneralLoader.h" -#include "Resource\OysterResource.h" const char* ShaderFunction = "main"; @@ -49,7 +48,7 @@ namespace Oyster case Oyster::Graphics::Core::PipelineManager::Vertex: if(!VSMap.count(name) || ForceReload) { - data = Resource::OysterResource::LoadResource(filename.c_str(),Loading::LoadShaderV, -1, ForceReload); + data = Core::loader.LoadResource(filename.c_str(),Loading::LoadShaderV, Loading::UnloadShaderV, -1, ForceReload); if(data) { if(ForceReload && VSMap.count(name)) @@ -65,7 +64,7 @@ namespace Oyster } break; case Oyster::Graphics::Core::PipelineManager::Hull: - data = Resource::OysterResource::LoadResource(filename.c_str(),Loading::LoadShaderH, -1, ForceReload); + data = Core::loader.LoadResource(filename.c_str(),Loading::LoadShaderH, Loading::UnloadShaderH, -1, ForceReload); if(!HSMap.count(name) || ForceReload) { if(data!=0) @@ -84,7 +83,7 @@ namespace Oyster } break; case Oyster::Graphics::Core::PipelineManager::Domain: - data = Resource::OysterResource::LoadResource(filename.c_str(),Loading::LoadShaderD, -1, ForceReload); + data = Core::loader.LoadResource(filename.c_str(),Loading::LoadShaderD, Loading::UnloadShaderD, -1, ForceReload); if(!DSMap.count(name) || ForceReload) { if(data!=0) @@ -102,7 +101,7 @@ namespace Oyster } break; case Oyster::Graphics::Core::PipelineManager::Geometry: - data = Resource::OysterResource::LoadResource(filename.c_str(),Loading::LoadShaderG, -1, ForceReload); + data = Core::loader.LoadResource(filename.c_str(),Loading::LoadShaderG, Loading::UnloadShaderG, -1, ForceReload); if(!GSMap.count(name) || ForceReload) { if(data!=0) @@ -120,7 +119,7 @@ namespace Oyster } break; case Oyster::Graphics::Core::PipelineManager::Pixel: - data = Resource::OysterResource::LoadResource(filename.c_str(),Loading::LoadShaderP, -1, ForceReload); + data = Core::loader.LoadResource(filename.c_str(),Loading::LoadShaderP, Loading::UnloadShaderP, -1, ForceReload); if(!PSMap.count(name) || ForceReload) { if(data!=0) @@ -138,7 +137,7 @@ namespace Oyster } break; case Oyster::Graphics::Core::PipelineManager::Compute: - data = Resource::OysterResource::LoadResource(filename.c_str(),Loading::LoadShaderC, -1, ForceReload); + data = Core::loader.LoadResource(filename.c_str(),Loading::LoadShaderC, Loading::UnloadShaderC, -1, ForceReload); if(!CSMap.count(name) || ForceReload) { if(data!=0) diff --git a/Code/OysterGraphics/Definitions/GraphicalDefinition.h b/Code/OysterGraphics/Definitions/GraphicalDefinition.h index d6529c48..d84f7506 100644 --- a/Code/OysterGraphics/Definitions/GraphicalDefinition.h +++ b/Code/OysterGraphics/Definitions/GraphicalDefinition.h @@ -14,12 +14,6 @@ namespace Oyster Oyster::Math::Float3 normal; }; - struct VP - { - Oyster::Math::Matrix V; - Oyster::Math::Matrix P; - }; - struct PerModel { Math::Matrix WV; @@ -55,6 +49,13 @@ namespace Oyster float Bright; }; + struct AnimationData + { + Math::Float4x4 animatedData[100]; + int Animated; + Math::Float3 Pad; + }; + } } } \ No newline at end of file diff --git a/Code/OysterGraphics/DllInterfaces/GFXAPI.cpp b/Code/OysterGraphics/DllInterfaces/GFXAPI.cpp index b508c600..2d9c3dc6 100644 --- a/Code/OysterGraphics/DllInterfaces/GFXAPI.cpp +++ b/Code/OysterGraphics/DllInterfaces/GFXAPI.cpp @@ -4,7 +4,8 @@ #include "../Render/Resources/Deffered.h" #include "../Render/Rendering/Render.h" #include "../FileLoader/ObjReader.h" -#include "../../Misc/Resource/OysterResource.h" +//#include "../../Misc/Resource/OysterResource.h" +#include "../../Misc/Resource/ResourceManager.h" #include "../FileLoader/GeneralLoader.h" #include "../Model/ModelInfo.h" #include @@ -73,6 +74,8 @@ namespace Oyster API::State API::SetOptions(API::Option option) { + Core::modelPath = option.modelPath; + Core::texturePath = option.texturePath; return API::Sucsess; } @@ -82,8 +85,8 @@ namespace Oyster Model::Model* m = new Model::Model(); m->WorldMatrix = Oyster::Math::Float4x4::identity; m->Visible = true; - - m->info = Oyster::Resource::OysterResource::LoadResource(filename.c_str(),Oyster::Graphics::Loading::LoadDAN); + m->AnimationPlaying = -1; + m->info = (Model::ModelInfo*)Core::loader.LoadResource((Core::modelPath + filename).c_str(),Oyster::Graphics::Loading::LoadDAN, Oyster::Graphics::Loading::UnloadDAN); Model::ModelInfo* mi = (Model::ModelInfo*)m->info; if(!mi || mi->Vertices->GetBufferPointer() == NULL) @@ -101,13 +104,13 @@ namespace Oyster return; Model::ModelInfo* info = (Model::ModelInfo*)model->info; delete model; - Oyster::Resource::OysterResource::ReleaseResource((Oyster::Resource::OHRESOURCE)info); + Core::loader.ReleaseResource(info); } void API::Clean() { SAFE_DELETE(Core::viewPort); - Oyster::Resource::OysterResource::Clean(); + Core::loader.Clean(); Oyster::Graphics::Core::PipelineManager::Clean(); Oyster::Graphics::Render::Resources::Deffered::Clean(); diff --git a/Code/OysterGraphics/DllInterfaces/GFXAPI.h b/Code/OysterGraphics/DllInterfaces/GFXAPI.h index 950ef19f..81a3bedc 100644 --- a/Code/OysterGraphics/DllInterfaces/GFXAPI.h +++ b/Code/OysterGraphics/DllInterfaces/GFXAPI.h @@ -26,6 +26,7 @@ namespace Oyster }; struct Option { + std::wstring modelPath, texturePath; }; static State Init(HWND Window, bool MSAA_Quality, bool Fullscreen, Oyster::Math::Float2 StartResulotion); diff --git a/Code/OysterGraphics/FileLoader/DanLoader.cpp b/Code/OysterGraphics/FileLoader/DanLoader.cpp index 6ac0cc24..0eff143a 100644 --- a/Code/OysterGraphics/FileLoader/DanLoader.cpp +++ b/Code/OysterGraphics/FileLoader/DanLoader.cpp @@ -102,211 +102,320 @@ struct MaterialHeader /// struct SkeletonHeader { - // do this... + unsigned int numBones; + + /// + SkeletonHeader(char* data) + { + memcpy(&numBones, data, sizeof(unsigned int)); + } }; /// struct AnimationHeader { - // do this... -}; + unsigned int numAnims; -struct Frame -{ - // do this... + + AnimationHeader(char* data) + { + memcpy(&numAnims, data, sizeof(unsigned int)); + } }; /// -void Oyster::Graphics::Loading::UnloadDAN(void* data) -{ - Model::ModelInfo* info = (Model::ModelInfo*) data; - SAFE_DELETE(info->Vertices); - if(info->Indexed) - { - SAFE_DELETE(info->Indecies); - } - for(int i =0;iMaterial.size();++i) - { - Oyster::Resource::OysterResource::ReleaseResource(info->Material[i]); - } - delete info; -} - -static std::wstring charToWChar(const char* text) +void Oyster::Graphics::Loading::UnloadDAN(void* data) { - // Convert to a wchar_t* - size_t origsize = strlen(text) + 1; - size_t convertedChars = 0; - //wchar_t* wcstring = new wchar_t[origsize]; - std::wstring wcstring; wcstring.resize(origsize); - mbstowcs_s(&convertedChars, &wcstring[0], origsize, text, _TRUNCATE); + Model::ModelInfo* info = (Model::ModelInfo*) data; + SAFE_DELETE(info->Vertices); + if(info->Indexed) + { + SAFE_DELETE(info->Indecies); + } + if(info->Animated) + { + //clean animation + delete[] info->bones; + for(int a = 0; a < info->AnimationCount; ++a) + { + for(int x = 0; x < info->Animations[a].Bones; ++x) + { + delete[] info->Animations[a].Keyframes[x]; + } + delete[] info->Animations[a].Frames; + delete[] info->Animations[a].Keyframes; + } + delete[] info->Animations; + } + for(int i =0;iMaterial.size();++i) + { + Core::loader.ReleaseResource(info->Material[i]); + } + delete info; +} + +static wchar_t* charToWChar(const char* text) +{ + // Convert to a wchar_t* + size_t origsize = strlen(text) + 1; + size_t convertedChars = 0; + wchar_t* wcstring = new wchar_t[origsize]; + mbstowcs_s(&convertedChars, wcstring, origsize, text, _TRUNCATE); return wcstring; -} - -/// -void Oyster::Graphics::Loading::LoadDAN(const wchar_t filename[], Oyster::Resource::CustomData& out) -{ - // - Oyster::Graphics::Model::ModelInfo* modelInfo = new Oyster::Graphics::Model::ModelInfo(); - modelInfo->Indexed = false; - // Open file in binary mode +} + +static void ReadData(void* Destination, std::ifstream& file, int size) +{ + char* buffer = new char[size]; + file.read(buffer,size); + memcpy(Destination,buffer,size); + delete[] buffer; +} + +/// +void* Oyster::Graphics::Loading::LoadDAN(const wchar_t filename[]) +{ + // + Oyster::Graphics::Model::ModelInfo* modelInfo = new Oyster::Graphics::Model::ModelInfo(); + modelInfo->Indexed = false; + modelInfo->Animated = false; + // Open file in binary mode std::ifstream danFile; - danFile.open(filename, std::ios::binary); - if (!danFile.is_open()) - return; - - // Read file header - char* buffer = new char[sizeof(FileHeader)]; - danFile.read(buffer, sizeof(FileHeader)); - FileHeader fileHeader(buffer); - delete[] buffer; // ( note: may crash here.) - - // If problem with compatability then close file and return from method - if (fileHeader.versionMajor != DANFILEVERSIONMAJOR) - { - danFile.close(); - return; - } - - // Read the .dan-file - while (!danFile.eof()) - { - // read header type - unsigned int headerType; - buffer = new char[4]; - danFile.read(buffer, 4); - memcpy(&headerType, buffer, 4); - delete[] buffer; // ( note: may crash here.) - - // handle header type - switch ((HeaderType)headerType) - { - // vertex header - case HeaderType::VERTEXHEADER: - { - // Fetch vertex header, number of vertices - buffer = new char[4]; - danFile.read(buffer, 4); - VertexHeader vertexHeader(buffer); - delete[] buffer; // ( note: may crash here.) - - // Fetch all vertices - Vertex* vertices = new Vertex[vertexHeader.numVertices]; - unsigned int bufferSize = VERTEXSIZE * vertexHeader.numVertices; - buffer = new char[bufferSize]; - danFile.read(buffer, bufferSize); - memcpy(vertices, buffer, bufferSize); - delete[] buffer; // ( note: may crash here.) - - // Do the deed - Oyster::Graphics::Core::Buffer* vertexBuffer = new Oyster::Graphics::Core::Buffer(); - Oyster::Graphics::Core::Buffer::BUFFER_INIT_DESC bufferInitDesc; - bufferInitDesc.ElementSize = sizeof(Vertex); - bufferInitDesc.InitData = vertices; - bufferInitDesc.NumElements = vertexHeader.numVertices; - bufferInitDesc.Type = Oyster::Graphics::Core::Buffer::BUFFER_TYPE::VERTEX_BUFFER; - bufferInitDesc.Usage = Oyster::Graphics::Core::Buffer::BUFFER_USAGE::BUFFER_DEFAULT; - vertexBuffer->Init(bufferInitDesc); - modelInfo->VertexCount = vertexHeader.numVertices; - modelInfo->Vertices = vertexBuffer; - - delete[] vertices; // ( note: may crash here.) - - break; - } - case HeaderType::INDEXHEADER: - { - // Fetch vertex header, number of vertices - buffer = new char[4]; - danFile.read(buffer, 4); - IndexHeader indexHeader(buffer); - delete[] buffer; // ( note: may crash here.) - - // Fetch all indices - unsigned int* indices = new unsigned int[indexHeader.numIndices]; - unsigned int bufferSize = sizeof(unsigned int) * indexHeader.numIndices; - buffer = new char[bufferSize]; - danFile.read(buffer, bufferSize); - memcpy(indices, buffer, bufferSize); - delete[] buffer; // ( note: may crash here.) - - // Do the deed - Oyster::Graphics::Core::Buffer* indexBuffer = new Oyster::Graphics::Core::Buffer(); - Oyster::Graphics::Core::Buffer::BUFFER_INIT_DESC bufferInitDesc; - bufferInitDesc.ElementSize = sizeof(unsigned int); - bufferInitDesc.InitData = indices; - bufferInitDesc.NumElements = indexHeader.numIndices; - bufferInitDesc.Type = Oyster::Graphics::Core::Buffer::BUFFER_TYPE::INDEX_BUFFER; - bufferInitDesc.Usage = Oyster::Graphics::Core::Buffer::BUFFER_USAGE::BUFFER_DEFAULT; - indexBuffer->Init(bufferInitDesc); - modelInfo->IndexCount = indexHeader.numIndices; - modelInfo->Indecies = indexBuffer; - modelInfo->Indexed = true; - - delete[] indices; // ( note: may crash here.) - - break; - } - // material header - case HeaderType::MATERIALHEADER: - { - // Fetch material header, 2 texture path strings - MaterialHeader materialHeader; - buffer = new char[4]; - danFile.read(buffer, 4); - memcpy(&materialHeader.diffuseMapPathLength, buffer, 4); - delete[] buffer; // ( note: may crash here.) + danFile.open(filename, std::ios::binary); + if (!danFile.is_open()) + return NULL; - buffer = new char[materialHeader.diffuseMapPathLength]; - danFile.read(buffer, materialHeader.diffuseMapPathLength); + // Read file header + char* buffer = new char[sizeof(FileHeader)]; + danFile.read(buffer, sizeof(FileHeader)); + FileHeader fileHeader(buffer); + delete[] buffer; // ( note: may crash here.) + + // If problem with compatability then close file and return from method + if (fileHeader.versionMajor != DANFILEVERSIONMAJOR) + { + danFile.close(); + return NULL; + } + + // Read the .dan-file + while (!danFile.eof()) + { + // read header type + unsigned int headerType; + ReadData(&headerType,danFile,4); + + // handle header type + switch ((HeaderType)headerType) + { + // vertex header + case HeaderType::VERTEXHEADER: + { + // Fetch vertex header, number of vertices + buffer = new char[4]; + danFile.read(buffer, 4); + VertexHeader vertexHeader(buffer); + delete[] buffer; // ( note: may crash here.) + + // Fetch all vertices + unsigned int bufferSize = VERTEXSIZE * vertexHeader.numVertices; + buffer = new char[bufferSize]; + danFile.read(buffer, bufferSize); + + // Do the deed + Oyster::Graphics::Core::Buffer* vertexBuffer = new Oyster::Graphics::Core::Buffer(); + Oyster::Graphics::Core::Buffer::BUFFER_INIT_DESC bufferInitDesc; + bufferInitDesc.ElementSize = sizeof(Vertex); + bufferInitDesc.InitData = buffer; + bufferInitDesc.NumElements = vertexHeader.numVertices; + bufferInitDesc.Type = Oyster::Graphics::Core::Buffer::BUFFER_TYPE::VERTEX_BUFFER; + bufferInitDesc.Usage = Oyster::Graphics::Core::Buffer::BUFFER_USAGE::BUFFER_DEFAULT; + vertexBuffer->Init(bufferInitDesc); + modelInfo->VertexCount = vertexHeader.numVertices; + modelInfo->Vertices = vertexBuffer; + + + delete[] buffer; // ( note: may crash here.) + + break; + } + case HeaderType::INDEXHEADER: + { + // Fetch vertex header, number of vertices + buffer = new char[4]; + danFile.read(buffer, 4); + IndexHeader indexHeader(buffer); + delete[] buffer; // ( note: may crash here.) + + // Fetch all indices + unsigned int* indices = new unsigned int[indexHeader.numIndices]; + unsigned int bufferSize = sizeof(unsigned int) * indexHeader.numIndices; + + + ReadData(indices,danFile,bufferSize); + + // Do the deed + Oyster::Graphics::Core::Buffer* indexBuffer = new Oyster::Graphics::Core::Buffer(); + Oyster::Graphics::Core::Buffer::BUFFER_INIT_DESC bufferInitDesc; + bufferInitDesc.ElementSize = sizeof(unsigned int); + bufferInitDesc.InitData = indices; + bufferInitDesc.NumElements = indexHeader.numIndices; + bufferInitDesc.Type = Oyster::Graphics::Core::Buffer::BUFFER_TYPE::INDEX_BUFFER; + bufferInitDesc.Usage = Oyster::Graphics::Core::Buffer::BUFFER_USAGE::BUFFER_DEFAULT; + indexBuffer->Init(bufferInitDesc); + modelInfo->IndexCount = indexHeader.numIndices; + modelInfo->Indecies = indexBuffer; + modelInfo->Indexed = true; + + delete[] indices; // ( note: may crash here.) + + break; + } + // material header + case HeaderType::MATERIALHEADER: + { + // Fetch material header, 2 texture path strings + MaterialHeader materialHeader; + + //read difuse map name length + ReadData(&materialHeader.diffuseMapPathLength,danFile,4); + + //read diffuse map name materialHeader.diffuseMapPath = new char[materialHeader.diffuseMapPathLength+1]; - memcpy(materialHeader.diffuseMapPath, buffer, materialHeader.diffuseMapPathLength); - materialHeader.diffuseMapPath[materialHeader.diffuseMapPathLength] = 0; - delete[] buffer; // ( note: may crash here.) - - buffer = new char[4]; - danFile.read(buffer, 4); - memcpy(&materialHeader.normalMapPathLength, buffer, 4); - delete[] buffer; // ( note: may crash here.) + ReadData(materialHeader.diffuseMapPath,danFile,materialHeader.diffuseMapPathLength); + //null terminate + materialHeader.diffuseMapPath[materialHeader.diffuseMapPathLength] = 0; + + //read normal map name length + ReadData(&materialHeader.normalMapPathLength,danFile,4); - buffer = new char[materialHeader.normalMapPathLength]; - danFile.read(buffer, materialHeader.normalMapPathLength); + //read difuse map name materialHeader.normalMapPath = new char[materialHeader.normalMapPathLength + 1]; - memcpy(materialHeader.normalMapPath, buffer, materialHeader.normalMapPathLength); - materialHeader.normalMapPath[materialHeader.normalMapPathLength] = 0; - delete[] buffer; // ( note: may crash here.) - - // - ID3D11ShaderResourceView* diffuseMap = (ID3D11ShaderResourceView*)Oyster::Resource::OysterResource::LoadResource(charToWChar(materialHeader.diffuseMapPath).c_str(), Oyster::Graphics::Loading::LoadTexture); - ID3D11ShaderResourceView* normalMap = (ID3D11ShaderResourceView*)Oyster::Resource::OysterResource::LoadResource(charToWChar(materialHeader.normalMapPath).c_str(), Oyster::Graphics::Loading::LoadTexture); - modelInfo->Material.push_back(diffuseMap); - modelInfo->Material.push_back(normalMap); - - delete materialHeader.normalMapPath; - delete materialHeader.diffuseMapPath; - - break; - } - // skeleton header - case HeaderType::SKELETONHEADER: - { - // not implemented... - break; - } - // animation header - case HeaderType::ANIMATIONHEADER: - { - // not implemented... - break; - } - } - } - - - // close file - danFile.close(); - - // Set modelinfo as output data - out.loadedData = modelInfo; - out.resourceUnloadFnc = Oyster::Graphics::Loading::UnloadDAN; + ReadData(materialHeader.normalMapPath,danFile,materialHeader.normalMapPathLength); + materialHeader.normalMapPath[materialHeader.normalMapPathLength] = 0; + + //load diffuse map + wchar_t* path = charToWChar(materialHeader.diffuseMapPath); + ID3D11ShaderResourceView* diffuseMap = (ID3D11ShaderResourceView*)Core::loader.LoadResource((Core::texturePath + path).c_str(), Oyster::Graphics::Loading::LoadTexture, Oyster::Graphics::Loading::UnloadTexture); + delete[] path; + + //load normal map + path = charToWChar(materialHeader.normalMapPath); + ID3D11ShaderResourceView* normalMap = (ID3D11ShaderResourceView*)Core::loader.LoadResource((Core::texturePath + path).c_str(), Oyster::Graphics::Loading::LoadTexture, Oyster::Graphics::Loading::UnloadTexture); + delete[] path; + + //add to model + modelInfo->Material.push_back(diffuseMap); + modelInfo->Material.push_back(normalMap); + + //clean up + delete[] materialHeader.diffuseMapPath; + delete[] materialHeader.normalMapPath; + + break; + } + + // skeleton header + case HeaderType::SKELETONHEADER: + { + // Fetch Skeleton header, number of Bones + buffer = new char[4]; + danFile.read(buffer, 4); + SkeletonHeader skeletonHeader(buffer); + delete[] buffer; // ( note: may crash here.) + + //array for bone data + Oyster::Graphics::Model::Bone* bones = new Oyster::Graphics::Model::Bone[skeletonHeader.numBones]; + + //read bones + ReadData(bones,danFile,skeletonHeader.numBones * sizeof(Oyster::Graphics::Model::Bone)); + + + //read skeleton Hiarchy + + modelInfo->BoneCount = skeletonHeader.numBones; + modelInfo->bones = bones; + + break; + } + // animation header + case HeaderType::ANIMATIONHEADER: + { + //get num anims + buffer = new char[4]; + danFile.read(buffer, 4); + AnimationHeader animationHeader(buffer); + delete[] buffer; + + Oyster::Graphics::Model::Animation* anims = new Oyster::Graphics::Model::Animation[animationHeader.numAnims]; + + for(int a = 0; a < animationHeader.numAnims; ++a) + { + //read name of animation + int nameLength; + + + ReadData(&nameLength,danFile,4); + + char* name = new char[nameLength + 1]; + ReadData(name,danFile,nameLength); + name[nameLength] = 0; + + wchar_t* wName = charToWChar(name); + anims[a].name = std::wstring(wName); + delete[] wName; + delete name; + + //read nr of bones in animation + ReadData(&anims[a].Bones,danFile,4); + + //read duration + ReadData(&anims[a].duration,danFile,8); + + //create Frame array and Bone part of KeyFrameArray; + anims[a].Frames = new int[anims[a].Bones]; + anims[a].Keyframes = new Oyster::Graphics::Model::Frame*[anims[a].Bones]; + + //loop per bone and gather data + for(int b = 0; b < anims[a].Bones; ++b) + { + + //read bone index + int boneIndex; + ReadData(&boneIndex,danFile,4); + + //read nr of frames per bone + ReadData(&anims[a].Frames[b],danFile,4); + + //create frame matrix + anims[a].Keyframes[b] = new Oyster::Graphics::Model::Frame[anims[a].Frames[b]]; + + + for(int f = 0; f < anims[a].Frames[b]; ++f) + { + //write index of bone + anims[a].Keyframes[b][f].bone.Parent = boneIndex; + + //read bone transform + ReadData(&anims[a].Keyframes[b][f].bone.Transform,danFile,sizeof(Oyster::Math::Matrix)); + + + ReadData(&anims[a].Keyframes[b][f].time,danFile,sizeof(double)); + } + } + } + modelInfo->AnimationCount = animationHeader.numAnims; + modelInfo->Animations = anims; + modelInfo->Animated = true; + + break; + } + } + } + + // close file + danFile.close(); + + // Set modelinfo as output data + return modelInfo; } \ No newline at end of file diff --git a/Code/OysterGraphics/FileLoader/GeneralLoader.h b/Code/OysterGraphics/FileLoader/GeneralLoader.h index cd6806e1..4a707699 100644 --- a/Code/OysterGraphics/FileLoader/GeneralLoader.h +++ b/Code/OysterGraphics/FileLoader/GeneralLoader.h @@ -1,5 +1,4 @@ #pragma once -#include "..\..\Misc\Resource\OysterResource.h" namespace Oyster { namespace Graphics @@ -7,31 +6,31 @@ namespace Oyster namespace Loading { void UnloadTexture(void* loadedData); - void LoadTexture(const wchar_t filename[], Oyster::Resource::CustomData& out); + void* LoadTexture(const wchar_t filename[]); void UnloadShaderP(void* loadedData); - void LoadShaderP(const wchar_t filename[], Oyster::Resource::CustomData& out); + void* LoadShaderP(const wchar_t filename[]); void UnloadShaderG(void* loadedData); - void LoadShaderG(const wchar_t filename[], Oyster::Resource::CustomData& out); + void* LoadShaderG(const wchar_t filename[]); void UnloadShaderC(void* loadedData); - void LoadShaderC(const wchar_t filename[], Oyster::Resource::CustomData& out); + void* LoadShaderC(const wchar_t filename[]); void UnloadShaderV(void* loadedData); - void LoadShaderV(const wchar_t filename[], Oyster::Resource::CustomData& out); + void* LoadShaderV(const wchar_t filename[]); void UnloadShaderH(void* loadedData); - void LoadShaderH(const wchar_t filename[], Oyster::Resource::CustomData& out); + void* LoadShaderH(const wchar_t filename[]); void UnloadShaderD(void* loadedData); - void LoadShaderD(const wchar_t filename[], Oyster::Resource::CustomData& out); + void* LoadShaderD(const wchar_t filename[]); void UnloadOBJ(void* loadedData); - void LoadOBJ(const wchar_t filename[], Oyster::Resource::CustomData& out); + void* LoadOBJ(const wchar_t filename[]); void UnloadDAN(void* loadedData); - void LoadDAN(const wchar_t filename[], Oyster::Resource::CustomData& out); + void* LoadDAN(const wchar_t filename[]); } } } \ No newline at end of file diff --git a/Code/OysterGraphics/FileLoader/ModelLoader.cpp b/Code/OysterGraphics/FileLoader/ModelLoader.cpp index cfd61e0d..b7b8b09a 100644 --- a/Code/OysterGraphics/FileLoader/ModelLoader.cpp +++ b/Code/OysterGraphics/FileLoader/ModelLoader.cpp @@ -2,7 +2,6 @@ #include "..\Core\Dx11Includes.h" #include "..\Core\Core.h" #include "ObjReader.h" -#include "..\..\Misc\Resource\OysterResource.h" HRESULT CreateWICTextureFromFileEx( ID3D11Device* d3dDevice, ID3D11DeviceContext* d3dContext, @@ -16,18 +15,17 @@ HRESULT CreateWICTextureFromFileEx( ID3D11Device* d3dDevice, ID3D11Resource** texture, ID3D11ShaderResourceView** textureView ); -void Oyster::Graphics::Loading::LoadTexture(const wchar_t filename[], Oyster::Resource::CustomData& out) +void* Oyster::Graphics::Loading::LoadTexture(const wchar_t filename[]) { ID3D11ShaderResourceView* srv = NULL; HRESULT hr = CreateWICTextureFromFileEx(Core::device,Core::deviceContext,filename,0,D3D11_USAGE_DEFAULT,D3D11_BIND_SHADER_RESOURCE,0,0,false,NULL,&srv); if(hr!=S_OK) { - memset(&out,0,sizeof(out)); + return NULL; } else { - out.loadedData = (void*)srv; - out.resourceUnloadFnc = Loading::UnloadTexture; + return srv; } } @@ -37,7 +35,7 @@ void Oyster::Graphics::Loading::UnloadTexture(void* data) SAFE_RELEASE(srv); } -void Oyster::Graphics::Loading::LoadOBJ(const wchar_t filename[], Oyster::Resource::CustomData& out) +void* Oyster::Graphics::Loading::LoadOBJ(const wchar_t filename[]) { FileLoaders::ObjReader obj; obj.LoadFile(filename); @@ -57,12 +55,11 @@ void Oyster::Graphics::Loading::LoadOBJ(const wchar_t filename[], Oyster::Resour info->Vertices->Init(desc); info->Indexed = false; - void* texture = Oyster::Resource::OysterResource::LoadResource((std::wstring(filename)+ L".png").c_str(),Graphics::Loading::LoadTexture); + void* texture = Core::loader.LoadResource((std::wstring(filename)+ L".png").c_str(),Graphics::Loading::LoadTexture, Graphics::Loading::UnloadTexture); info->Material.push_back((ID3D11ShaderResourceView*)texture); - out.loadedData = info; - out.resourceUnloadFnc = Oyster::Graphics::Loading::UnloadOBJ; + return info; } void Oyster::Graphics::Loading::UnloadOBJ(void* data) @@ -75,7 +72,7 @@ void Oyster::Graphics::Loading::UnloadOBJ(void* data) } for(int i =0;iMaterial.size();++i) { - Oyster::Resource::OysterResource::ReleaseResource(info->Material[i]); + Core::loader.ReleaseResource(info->Material[i]); } delete info; } diff --git a/Code/OysterGraphics/FileLoader/ShaderLoader.cpp b/Code/OysterGraphics/FileLoader/ShaderLoader.cpp index 9a8cff37..5edc86dd 100644 --- a/Code/OysterGraphics/FileLoader/ShaderLoader.cpp +++ b/Code/OysterGraphics/FileLoader/ShaderLoader.cpp @@ -10,7 +10,7 @@ namespace Oyster { namespace Loading { - void LoadShader(const wchar_t filename[], Oyster::Resource::CustomData& out, int type); + void* LoadShader(const wchar_t filename[], int type); void UnloadShaderP(void* loadedData) { @@ -48,78 +48,41 @@ namespace Oyster SAFE_RELEASE(ps); } - void LoadShaderP(const wchar_t filename[], Oyster::Resource::CustomData& out) + void* LoadShaderP(const wchar_t filename[]) { - LoadShader(filename,out,Core::PipelineManager::Pixel); - if(out.loadedData==NULL) - { - memset(&out,0,sizeof(out)); - return; - } - out.resourceUnloadFnc = UnloadShaderP; + return LoadShader(filename,Core::PipelineManager::Pixel); } - void LoadShaderG(const wchar_t filename[], Oyster::Resource::CustomData& out) + void* LoadShaderG(const wchar_t filename[]) { - LoadShader(filename,out,Core::PipelineManager::Geometry); - if(out.loadedData==NULL) - { - memset(&out,0,sizeof(out)); - return; - } - out.resourceUnloadFnc = UnloadShaderG; + return LoadShader(filename,Core::PipelineManager::Geometry); } - void LoadShaderC(const wchar_t filename[], Oyster::Resource::CustomData& out) + void* LoadShaderC(const wchar_t filename[]) { - LoadShader(filename,out,Core::PipelineManager::Compute); - if(out.loadedData==NULL) - { - memset(&out,0,sizeof(out)); - return; - } - out.resourceUnloadFnc = UnloadShaderC; + return LoadShader(filename,Core::PipelineManager::Compute); } - void LoadShaderH(const wchar_t filename[], Oyster::Resource::CustomData& out) + void* LoadShaderH(const wchar_t filename[]) { - LoadShader(filename,out,Core::PipelineManager::Hull); - if(out.loadedData==NULL) - { - memset(&out,0,sizeof(out)); - return; - } - out.resourceUnloadFnc = UnloadShaderH; + return LoadShader(filename,Core::PipelineManager::Hull); } - void LoadShaderD(const wchar_t filename[], Oyster::Resource::CustomData& out) + void* LoadShaderD(const wchar_t filename[]) { - LoadShader(filename,out,Core::PipelineManager::Domain); - if(out.loadedData==NULL) - { - memset(&out,0,sizeof(out)); - return; - } - out.resourceUnloadFnc = UnloadShaderD; + return LoadShader(filename,Core::PipelineManager::Domain); } - void LoadShaderV(const wchar_t filename[], Oyster::Resource::CustomData& out) + void* LoadShaderV(const wchar_t filename[]) { - - LoadShader(filename,out,Core::PipelineManager::Vertex); - if(out.loadedData==NULL) - { - memset(&out,0,sizeof(out)); - return; - } - out.resourceUnloadFnc = UnloadShaderV; + return LoadShader(filename,Core::PipelineManager::Vertex); } - void LoadShader(const wchar_t filename[], Oyster::Resource::CustomData& out, int type) + void* LoadShader(const wchar_t filename[], int type) { Core::PipelineManager::ShaderData data; #ifdef _DEBUG @@ -159,8 +122,7 @@ namespace Oyster { Shader->Release(); } - memset(&out,0,sizeof(out)); - return; + return NULL; } data.size = Shader->GetBufferSize(); @@ -181,11 +143,10 @@ namespace Oyster } else { - memset(&out,0,sizeof(out)); - return; + return NULL; } #endif - out.loadedData = Core::PipelineManager::CreateShader(data, Core::PipelineManager::ShaderType(type)); + return Core::PipelineManager::CreateShader(data, Core::PipelineManager::ShaderType(type)); } } } diff --git a/Code/OysterGraphics/Model/Model.h b/Code/OysterGraphics/Model/Model.h index 9fa5fb66..f4639c74 100644 --- a/Code/OysterGraphics/Model/Model.h +++ b/Code/OysterGraphics/Model/Model.h @@ -9,14 +9,14 @@ namespace Oyster { namespace Model { - //struct ModelInfo; + struct ModelInfo; struct Model { - //! do not Edit, linked to render data - //ModelInfo* info; - void* info; + ModelInfo* info; Oyster::Math::Float4x4 WorldMatrix; - bool Visible; + bool Visible, LoopAnimation; + int AnimationPlaying; + float AnimationTime; }; } diff --git a/Code/OysterGraphics/Model/ModelInfo.h b/Code/OysterGraphics/Model/ModelInfo.h index 9dcef562..3a184f65 100644 --- a/Code/OysterGraphics/Model/ModelInfo.h +++ b/Code/OysterGraphics/Model/ModelInfo.h @@ -11,12 +11,32 @@ namespace Oyster { namespace Model { + struct Bone + { + Math::Float4x4 Transform; + int Parent; + }; + struct Frame + { + Bone bone; + double time; + }; + struct Animation + { + std::wstring name; + int Bones; + int* Frames; //! Bone as index + Frame** Keyframes; //! @brief [Bone][Frame] + double duration; + }; struct ModelInfo { std::vector Material; Core::Buffer *Vertices,*Indecies; - bool Indexed; - int VertexCount, IndexCount; + bool Indexed, Animated; + int VertexCount, IndexCount, BoneCount, AnimationCount; + Bone* bones; + Animation* Animations; }; } } diff --git a/Code/OysterGraphics/Render/Rendering/BasicRender.cpp b/Code/OysterGraphics/Render/Rendering/BasicRender.cpp index 0a5a275c..113d7b6f 100644 --- a/Code/OysterGraphics/Render/Rendering/BasicRender.cpp +++ b/Code/OysterGraphics/Render/Rendering/BasicRender.cpp @@ -18,16 +18,10 @@ namespace Oyster void Basic::NewFrame(Oyster::Math::Float4x4 View, Oyster::Math::Float4x4 Projection, Definitions::Pointlight* Lights, int numLights) { Preparations::Basic::ClearBackBuffer(Oyster::Math::Float4(1,0,0,1)); - Preparations::Basic::ClearRTV(Resources::Deffered::GBufferRTV,Resources::Deffered::GBufferSize,Math::Float4(1,0,0,1)); + Preparations::Basic::ClearRTV(Resources::Deffered::GBufferRTV,Resources::Deffered::GBufferSize,Math::Float4(0,0,0,1)); Core::PipelineManager::SetRenderPass(Graphics::Render::Resources::Deffered::GeometryPass); - Definitions::VP vp; - vp.V = View; - vp.P = Projection; - - void* data = Resources::Deffered::VPData.Map(); - memcpy(data, &vp, sizeof(Definitions::VP)); - Resources::Deffered::VPData.Unmap(); + void* data; Definitions::LightConstants lc; lc.InvProj = Projection.GetInverse(); @@ -61,10 +55,79 @@ namespace Oyster void* data = Resources::Deffered::ModelData.Map(); memcpy(data,&(pm),sizeof(pm)); Resources::Deffered::ModelData.Unmap(); - Model::ModelInfo* info = (Model::ModelInfo*)models[i].info; + + + Definitions::AnimationData am; + if(info->Animated && models[i].AnimationPlaying != -1) + { + + Definitions::AnimationData am2; + //write default data + for (int b = 0; b < info->BoneCount; b++) + { + am2.animatedData[b] = info->bones[b].Transform; + } + //loop bones in animation + am.Animated = 1; + + + Model::Frame Prev, Next; + + models[i].AnimationTime = fmod(models[i].AnimationTime,info->Animations[models[i].AnimationPlaying].duration); + + for(int x = 0; x < info->Animations[models[i].AnimationPlaying].Bones; ++x) + { + //loop frame per bone + Prev.bone.Parent = 0; + Next = Prev; + for(int y = 0; y < info->Animations[models[i].AnimationPlaying].Frames[x]; ++y) + { + ///TODO replace with binary search? + Model::Frame f = info->Animations[models[i].AnimationPlaying].Keyframes[x][y]; + + //if we hit frame + if(models[i].AnimationTime == f.time) + { + Prev = f; + Next = f; + break; + } + + //if time is larger than frame time, store frames + if(models[i].AnimationTime < f.time) + { + Next = f; + Prev = info->Animations[models[i].AnimationPlaying].Keyframes[x][y-1]; + break; + } + } + + + //calculate interpolated bone position + + //rebase model time to between prev and next + float interpoation =(models[i].AnimationTime - Prev.time) / (Next.time - Prev.time); + + //interpolate + Math::Matrix Interpolated; + Math3D::InterpolateOrientation_UsingNonRigidNlerp(Prev.bone.Transform,Next.bone.Transform,interpoation, Interpolated); + + //write magic to animated data + am2.animatedData[Prev.bone.Parent] = Interpolated * am2.animatedData[info->bones[Prev.bone.Parent].Parent]; + //sneaky write do correct data buffer + am.animatedData[x] = (am2.animatedData[Prev.bone.Parent] * info->bones[Prev.bone.Parent].Transform.GetInverse()); + } + } + else + am.Animated = 0; + + data = Resources::Deffered::AnimationData.Map(); + memcpy(data,&am,sizeof(Definitions::AnimationData)); + Resources::Deffered::AnimationData.Unmap(); + if(info->Material.size()) { Core::deviceContext->PSSetShaderResources(0,(UINT)info->Material.size(),&(info->Material[0])); @@ -84,6 +147,8 @@ namespace Oyster } } } + + void Basic::EndFrame() { Core::PipelineManager::SetRenderPass(Resources::Deffered::LightPass); diff --git a/Code/OysterGraphics/Render/Resources/Deffered.cpp b/Code/OysterGraphics/Render/Resources/Deffered.cpp index f606d57e..361a94dd 100644 --- a/Code/OysterGraphics/Render/Resources/Deffered.cpp +++ b/Code/OysterGraphics/Render/Resources/Deffered.cpp @@ -12,7 +12,7 @@ const std::wstring PathToHLSL = L"..\\..\\Code\\OysterGraphics\\Shader\\HLSL\\De const std::wstring PathToCSO = L"..\\Content\\Shaders\\"; const int KernelSize = 10; -const int SampleSpread = 8; +const int SampleSpread = 16; namespace Oyster { @@ -34,7 +34,7 @@ namespace Oyster Shader::RenderPass Deffered::PostPass; Buffer Deffered::ModelData = Buffer(); - Buffer Deffered::VPData = Buffer(); + Buffer Deffered::AnimationData = Buffer(); Buffer Deffered::LightConstantsData = Buffer(); Buffer Deffered::PointLightsData = Buffer(); @@ -74,8 +74,9 @@ namespace Oyster ModelData.Init(desc); - desc.NumElements = 2; - VPData.Init(desc); + desc.NumElements = 1; + desc.ElementSize = sizeof(Definitions::AnimationData); + AnimationData.Init(desc); desc.ElementSize = sizeof(Definitions::LightConstants); desc.NumElements = 1; @@ -156,6 +157,7 @@ namespace Oyster Core::Init::CreateLinkedShaderResourceFromStructuredBuffer(&b,&PointLightView,NULL); srand((unsigned int)time(0)); + //SSAO Math::Vector3 kernel[KernelSize]; Math::Vector3 random[SampleSpread]; @@ -186,13 +188,12 @@ namespace Oyster { random[i] = Oyster::Math::Vector3( (float)rand() / (RAND_MAX + 1) * (1 - -1)+ -1, - (float)rand() / (RAND_MAX + 1) * (1 - -1)+ -1, + /*(float)rand() / (RAND_MAX + 1) * (1 - -1)+ -1,*/ + 1.0f, 0.0f); } random[i].Normalize(); } - //kernel[0] = Math::Vector3(0,1,1); - //kernel[0].Normalize(); D3D11_TEXTURE1D_DESC T1desc; T1desc.Width = KernelSize; @@ -208,17 +209,32 @@ namespace Oyster D3D11_SUBRESOURCE_DATA rnd; rnd.pSysMem = random; + rnd.SysMemPitch = sqrt(SampleSpread) * sizeof(Oyster::Math::Vector3); - ID3D11Texture1D *pTexture1[2]; + ID3D11Texture1D *pTexture1; - Core::device->CreateTexture1D( &T1desc, &sphere, &pTexture1[0] ); - Core::device->CreateShaderResourceView( pTexture1[0], 0, &SSAOKernel ); - pTexture1[0]->Release(); + Core::device->CreateTexture1D( &T1desc, &sphere, &pTexture1 ); + Core::device->CreateShaderResourceView( pTexture1, 0, &SSAOKernel ); + pTexture1->Release(); - T1desc.Width = SampleSpread; - Core::device->CreateTexture1D( &T1desc, &rnd, &pTexture1[1] ); - Core::device->CreateShaderResourceView( (pTexture1[1]), 0, &SSAORandom ); - pTexture1[1]->Release(); + D3D11_TEXTURE2D_DESC T2desc; + T2desc.Width = KernelSize; + T2desc.MipLevels = T2desc.ArraySize = 1; + T2desc.Format = DXGI_FORMAT_R32G32B32_FLOAT; + T2desc.Usage = D3D11_USAGE_DEFAULT; + T2desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + T2desc.CPUAccessFlags = 0; + T2desc.MiscFlags = 0; + T2desc.Height = sqrt(SampleSpread); + T2desc.Width = SampleSpread/sqrt(SampleSpread); + T2desc.SampleDesc.Quality = 0; + T2desc.SampleDesc.Count = 1; + + ID3D11Texture2D *pTexture2; + + Core::device->CreateTexture2D( &T2desc, &rnd, &pTexture2 ); + Core::device->CreateShaderResourceView( (pTexture2), 0, &SSAORandom ); + pTexture2->Release(); ////Create ShaderEffects @@ -239,7 +255,7 @@ namespace Oyster Shader::CreateInputLayout(indesc,7,GetShader::Vertex(L"Geometry"),GeometryPass.IAStage.Layout); GeometryPass.IAStage.Topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; - GeometryPass.CBuffers.Vertex.push_back(VPData); + GeometryPass.CBuffers.Vertex.push_back(AnimationData); GeometryPass.CBuffers.Vertex.push_back(ModelData); GeometryPass.RenderStates.Rasterizer = rs; GeometryPass.RenderStates.SampleCount = 1; @@ -281,7 +297,7 @@ namespace Oyster void Deffered::Clean() { Resources::Deffered::ModelData.~Buffer(); - Resources::Deffered::VPData.~Buffer(); + Resources::Deffered::AnimationData.~Buffer(); Resources::Deffered::LightConstantsData.~Buffer(); Resources::Deffered::PointLightsData.~Buffer(); SAFE_RELEASE(Resources::Deffered::PointLightView); diff --git a/Code/OysterGraphics/Render/Resources/Deffered.h b/Code/OysterGraphics/Render/Resources/Deffered.h index c4559cab..025da28b 100644 --- a/Code/OysterGraphics/Render/Resources/Deffered.h +++ b/Code/OysterGraphics/Render/Resources/Deffered.h @@ -18,12 +18,15 @@ namespace Oyster static const int LBufferSize = 3; static const int MaxLightSize = 100; //! GBuffers - //! 0 = Diffuse + SpecKoeff - //! 1 = Normal + Glow + //! 0 = Diffuse + Glow + //! 1 = Normal + Spec static ID3D11RenderTargetView* GBufferRTV[GBufferSize]; static ID3D11ShaderResourceView* GBufferSRV[GBufferSize]; - + //! LBuffer + //! 0 = Diffuse + //! 1 = Specular + //! 2 = SSAO static ID3D11UnorderedAccessView* LBufferUAV[LBufferSize]; static ID3D11ShaderResourceView* LBufferSRV[LBufferSize]; @@ -33,7 +36,7 @@ namespace Oyster static Core::Buffer ModelData; - static Core::Buffer VPData; + static Core::Buffer AnimationData; static Core::Buffer LightConstantsData; diff --git a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/Defines.hlsli b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/Defines.hlsli index 9096045d..1f1061d1 100644 --- a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/Defines.hlsli +++ b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/Defines.hlsli @@ -32,10 +32,10 @@ Texture2D DepthTexture : register(t2); StructuredBuffer Points : register(t3); Texture1D SSAOKernel : register(t4); -Texture1D SSAORand : register(t5); +Texture2D SSAORand : register(t5); RWTexture2D Diffuse : register(u0); RWTexture2D Specular : register(u1); -RWTexture2D Ambient : register(u2); +RWTexture2D Ambient : register(u2); #endif \ No newline at end of file diff --git a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/GBufferHeader.hlsli b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/GBufferHeader.hlsli index 18cac11d..f28c1b0b 100644 --- a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/GBufferHeader.hlsli +++ b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/GBufferHeader.hlsli @@ -30,11 +30,11 @@ Texture2D Normal : register(t1); SamplerState S1 : register(s0); -cbuffer PerFrame : register(b0) +cbuffer Animation : register(b0) { - matrix View; - float4x4 Projection; - matrix VP; + float4x4 BoneAnimation[100]; + int Animated; + float3 Pad; } cbuffer PerModel : register(b1) diff --git a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/LightCalc.hlsli b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/LightCalc.hlsli index bd449209..8a1ff05a 100644 --- a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/LightCalc.hlsli +++ b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/LightCalc.hlsli @@ -21,8 +21,8 @@ DiffSpec LightCalc(PointLight pl, float3 pos, int2 texCoord) output.Specular * 0; if(d > pl.Radius) { - output.Diffuse = float4(0,0,0,1); - output.Specular = float4(0,0,0,1); + output.Diffuse = float3(0,0,0); + output.Specular = float3(0,0,0); } return output; } \ No newline at end of file diff --git a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/LightPass.hlsl b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/LightPass.hlsl index 1efb94c6..d10484ef 100644 --- a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/LightPass.hlsl +++ b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/LightPass.hlsl @@ -12,13 +12,13 @@ [numthreads(16, 16, 1)] void main( uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID ) { - float2 UV = DTid / Pixels; + float2 UV = DTid.xy / Pixels; UV.x = UV.x * 2 - 1; UV.y = 1 - 2 * UV.y; float3 ViewPos = ToVpos(DTid.xy, UV); DiffSpec Shaded; - Shaded.Diffuse = float4(0,0,0,0); - Shaded.Specular = float4(0,0,0,0); + Shaded.Diffuse = float3(0,0,0); + Shaded.Specular = float3(0,0,0); for(int i = 0; i < Lights; ++i) { @@ -33,10 +33,10 @@ void main( uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID ) Specular[DTid.xy] = float4(Shaded.Specular, 1); - if((DTid.x + DTid.y) %4 == 0 ) + if(DTid.x & 1 && DTid.y & 1 ) { - float AmbValue = GetSSAO(ViewPos, UV, DTid.xy, GTid.xy); - Ambient[DTid.xy/4] = AmbValue; + float AmbValue = GetSSAO(ViewPos, UV, DTid.xy, GTid.xy/2); + Ambient[DTid.xy/2] = AmbValue; } } \ No newline at end of file diff --git a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/PostPass.hlsl b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/PostPass.hlsl index 3e03dfcd..612319e5 100644 --- a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/PostPass.hlsl +++ b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/PostPass.hlsl @@ -7,8 +7,7 @@ RWTexture2D Output; [numthreads(16, 16, 1)] void main( uint3 DTid : SV_DispatchThreadID ) { - Output[DTid.xy] = Diffuse[DTid.xy] + Specular[DTid.xy] + Diffuse[DTid.xy] * Ambient[DTid.xy/4].w;// + float4(Ambient[DTid.xy/4].xyz,1); GLOW - //Output[DTid.xy] = Diffuse[DTid.xy] + Diffuse[DTid.xy] * Ambient[DTid.xy/4].w;// + float4(Ambient[DTid.xy/4].xyz,1); GLOW - - //Output[DTid.xy] = Diffuse[DTid.xy]; + //Output[DTid.xy] = Diffuse[DTid.xy] + Specular[DTid.xy] + Diffuse[DTid.xy] * Ambient[DTid.xy/2].w;// + float4(Ambient[DTid.xy/4].xyz,1); GLOW + //Output[DTid.xy] = Ambient[DTid.xy/2]; + Output[DTid.xy] = Diffuse[DTid.xy] + Specular[DTid.xy]; } \ No newline at end of file diff --git a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/SSAO.hlsli b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/SSAO.hlsli index 32f84f90..bf71b92b 100644 --- a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/SSAO.hlsli +++ b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/SSAO.hlsli @@ -1,30 +1,33 @@ #include "Defines.hlsli" #include "PosManipulation.hlsli" -static float Radius =5; +static float Radius = 100; float GetSSAO(float3 pos, float2 uv, int2 texCoord2, uint2 rndID) { float occlusion = 0.0f; //create sample coordinate system - float4 rnd = float4( SSAORand[(rndID.x + rndID.y) % SSAORand.Length.x].xyz, 0.0f ); + float4 rnd = float4( SSAORand[int2(rndID.x % (SSAORand.Length.x), rndID.y % (SSAORand.Length.y))].xyz, 0.0f ); rnd = normalize(rnd); - float3 normal = NormalSpec[uv].xyz; - float4 tangent = float4( normalize(rnd.xyz - (normal * dot(rnd.xyz, normal))), 0.0f ); - float4 biTangent = float4( cross(tangent.xyz, normal), 0.0f ); + float3 normal = NormalSpec[texCoord2].xyz; + float3 tangent = float3( normalize(rnd.xyz - (normal * dot(rnd.xyz, normal)))); + float3 biTangent = float3( cross(tangent.xyz, normal)); - float4x4 tbn = float4x4(tangent, biTangent, float4(normal,0), float4(pos*Radius,1)); + float3x3 tbn = float3x3(tangent, biTangent, normal); for( uint i = 0; i < SSAOKernel.Length.x; ++i ) { + //int i = 0; //take sample from localspace to viewspace - float4 sampled = mul(tbn, float4(SSAOKernel[i].xyz,1)); + + float3 sampled = mul(tbn, SSAOKernel[i].xyz); + sampled = sampled * Radius + pos; //project sample to get uv.xy - float4 ProjOffset = sampled; + float4 ProjOffset = float4(sampled,1); ProjOffset = mul(Proj, ProjOffset); float4 offset = ProjOffset; - float2 UV = offset; + float2 UV = offset.xy; offset /= offset.w; offset.xyz = offset.xyz * 0.5f + 0.5f; //extra invert y axis, DX11 @@ -39,7 +42,7 @@ float GetSSAO(float3 pos, float2 uv, int2 texCoord2, uint2 rndID) //compare to depth from sample float rangeCheck = (abs(pos.z - sampleDepth) < Radius) ? 1.0f : 0.0f; - occlusion += (sampleDepth >= sampled.z ? 1.0f : 0.0f) * rangeCheck; + occlusion += (sampleDepth <= sampled.z ? 1.0f : 0.0f) * rangeCheck; } occlusion /= (float)(SSAOKernel.Length.x); occlusion = 1.0f - occlusion; diff --git a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/VertexGatherData.hlsl b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/VertexGatherData.hlsl index 8a361ccf..7395e08d 100644 --- a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/VertexGatherData.hlsl +++ b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/VertexGatherData.hlsl @@ -3,6 +3,20 @@ VertexOut main( VertexIn input ) { VertexOut output; + /*input.pos = ( + (mul(BoneAnimation[input.boneIndex.x], input.pos) * input.boneWeight.x) + + (mul(BoneAnimation[input.boneIndex.y], input.pos) * input.boneWeight.y) + + (mul(BoneAnimation[input.boneIndex.z], input.pos) * input.boneWeight.z) + + (mul(BoneAnimation[input.boneIndex.w], input.pos) * input.boneWeight.w) + * Animated) + input.pos * int(1-Animated);*/ + + input.pos = ( + (mul(BoneAnimation[input.boneIndex.x], input.pos)/* * input.boneWeight.x*/) + * Animated) + input.pos * int(1-Animated); + + //float4x4 m = matrix(float4(1,0,0,0),float4(0,1,0,0), float4(0,0,1,0), float4(0,0,0,1)); + //input.pos = mul(BoneAnimation[0], float4(input.pos,1)); + //input.pos = mul(m, float4(input.pos,1)); output.pos = mul(WVP, float4(input.pos,1)); output.normal = mul(WV, float4(input.normal,0)).xyz; output.UV = input.UV; diff --git a/Code/Tester/MainTest.cpp b/Code/Tester/MainTest.cpp new file mode 100644 index 00000000..dcafe91f --- /dev/null +++ b/Code/Tester/MainTest.cpp @@ -0,0 +1,260 @@ +//-------------------------------------------------------------------------------------- +// File: TemplateMain.cpp +// +// BTH-D3D-Template +// +// Copyright (c) Stefan Petersson 2011. All rights reserved. +//-------------------------------------------------------------------------------------- +#define NOMINMAX +#include +#include +#include "DllInterfaces\GFXAPI.h" + + + +//-------------------------------------------------------------------------------------- +// Global Variables +//-------------------------------------------------------------------------------------- +HINSTANCE g_hInst = NULL; +HWND g_hWnd = NULL; +Oyster::Graphics::Model::Model* m = NULL; +Oyster::Graphics::Model::Model* m2 = NULL; +Oyster::Graphics::Model::Model* m3 = NULL; +Oyster::Math::Float4x4 V; +Oyster::Math::Float4x4 P; + + +//-------------------------------------------------------------------------------------- +// Forward declarations +//-------------------------------------------------------------------------------------- +HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow ); +LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); +HRESULT Render(float deltaTime); +HRESULT Update(float deltaTime); +HRESULT InitDirect3D(); + + + + +//-------------------------------------------------------------------------------------- +// Entry point to the program. Initializes everything and goes into a message processing +// loop. Idle time is used to render the scene. +//-------------------------------------------------------------------------------------- +int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow ) +{ + + BOOL b = SetDllDirectoryW(L"..\\DLL"); + + if( FAILED( InitWindow( hInstance, nCmdShow ) ) ) + return 0; + + if( FAILED( InitDirect3D() ) ) + return 0; + + __int64 cntsPerSec = 0; + QueryPerformanceFrequency((LARGE_INTEGER*)&cntsPerSec); + float secsPerCnt = 1.0f / (float)cntsPerSec; + + __int64 prevTimeStamp = 0; + QueryPerformanceCounter((LARGE_INTEGER*)&prevTimeStamp); + + std::string fps = "FPS:"; + char count[100]; + // Main message loop + MSG msg = {0}; + float fpsCounter = 0; + while(WM_QUIT != msg.message) + { + if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE) ) + { + TranslateMessage( &msg ); + DispatchMessage( &msg ); + } + else + { + __int64 currTimeStamp = 0; + QueryPerformanceCounter((LARGE_INTEGER*)&currTimeStamp); + float dt = (currTimeStamp - prevTimeStamp) * secsPerCnt; + + //render + Update(dt); + Render(dt); + fpsCounter += dt; + if(fpsCounter>0.1f) + { + sprintf_s(count, "%f",1/dt); + SetWindowTextA(g_hWnd, (fps + count).c_str()); + fpsCounter = 0; + } + prevTimeStamp = currTimeStamp; + } + } + + Oyster::Graphics::API::DeleteModel(m); + Oyster::Graphics::API::DeleteModel(m2); + Oyster::Graphics::API::DeleteModel(m3); + Oyster::Graphics::API::Clean(); + return (int) msg.wParam; +} + +//-------------------------------------------------------------------------------------- +// Register class and create window +//-------------------------------------------------------------------------------------- +HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow ) +{ + // Register class + WNDCLASSEX wcex; + wcex.cbSize = sizeof(WNDCLASSEX); + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = WndProc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = hInstance; + wcex.hIcon = 0; + wcex.hCursor = LoadCursor(NULL, IDC_ARROW); + wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wcex.lpszMenuName = NULL; + wcex.lpszClassName = L"BTH_D3D_Template"; + wcex.hIconSm = 0; + if( !RegisterClassEx(&wcex) ) + return E_FAIL; + + // Adjust and create window + g_hInst = hInstance; + RECT rc = { 0, 0, 1280, 720 }; + AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE ); + + if(!(g_hWnd = CreateWindow( + L"BTH_D3D_Template", + L"BTH - Direct3D 11.0 Template", + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + rc.right - rc.left, + rc.bottom - rc.top, + NULL, + NULL, + hInstance, + NULL))) + { + return E_FAIL; + } + + ShowWindow( g_hWnd, nCmdShow ); + + return S_OK; +} + + + +//-------------------------------------------------------------------------------------- +// Create Direct3D device and swap chain +//-------------------------------------------------------------------------------------- +HRESULT InitDirect3D() +{ + HRESULT hr = S_OK;; + + if(Oyster::Graphics::API::Init(g_hWnd,false,false, Oyster::Math::Float2( 1024, 768 )) == Oyster::Graphics::API::Fail) + { + return E_FAIL; + } + + m = Oyster::Graphics::API::CreateModel(L"untitled.dan"); + m2 = Oyster::Graphics::API::CreateModel(L"still.dan"); + m2->WorldMatrix = Oyster::Math3D::OrientationMatrix(Oyster::Math::Float3::null,Oyster::Math::Float3(0,5,0),Oyster::Math::Float3::null); + m2->AnimationPlaying = 0; + m2->AnimationTime = 0.0f; + //m3 = Oyster::Graphics::API::CreateModel(L"box_2.dan"); + //m3->WorldMatrix = Oyster::Math3D::OrientationMatrix(Oyster::Math::Float3::null,Oyster::Math::Float3(0,5,0),Oyster::Math::Float3::null); + + + P = Oyster::Math3D::ProjectionMatrix_Perspective(Oyster::Math::pi/2,1280.0f/720.0f,.1f,10000); + Oyster::Graphics::API::SetProjection(P); + + V = Oyster::Math3D::OrientationMatrix_LookAtDirection(Oyster::Math::Float3(0,0,-1),Oyster::Math::Float3(0,1,0),Oyster::Math::Float3(0,200,500.4f)); + V = V.GetInverse(); + + + Oyster::Graphics::Definitions::Pointlight pl; + pl.Color = Oyster::Math::Float3(1,1,1); + pl.Bright = 1; + pl.Pos = Oyster::Math::Float3(0,-20.0f,30.4f); + pl.Radius = 90; + + Oyster::Graphics::API::AddLight(pl); + + + return S_OK; +} +float angle = 0; +HRESULT Update(float deltaTime) +{ + + angle += Oyster::Math::pi/16 * deltaTime; + //m->WorldMatrix = Oyster::Math3D::RotationMatrix_AxisY(angle) * Oyster::Math3D::RotationMatrix_AxisX(-Oyster::Math::pi/2); + m2->WorldMatrix = Oyster::Math3D::OrientationMatrix(Oyster::Math::Float3(0,1,0)*-Oyster::Math::pi/2,Oyster::Math::Float3(0,-4,0),Oyster::Math::Float3::null); + Oyster::Math::Matrix ma = Oyster::Math::Matrix::identity; + ma *= 50; + ma.m44 = 1; + m2->WorldMatrix = m2->WorldMatrix * ma; + m2->AnimationTime += deltaTime * 0.5f; + //m3->WorldMatrix = Oyster::Math3D::OrientationMatrix(Oyster::Math::Float3(1,0,0)*-0,Oyster::Math::Float3(3,4,-1*angle),Oyster::Math::Float3::null); + return S_OK; +} + +HRESULT Render(float deltaTime) +{ + Oyster::Graphics::API::SetView(V); + Oyster::Graphics::API::NewFrame(); + + //Oyster::Graphics::API::RenderModel(*m); + Oyster::Graphics::API::RenderModel(*m2); + //Oyster::Graphics::API::RenderModel(*m3); + + Oyster::Graphics::API::EndFrame(); + + return S_OK; +} + +//-------------------------------------------------------------------------------------- +// Called every time the application receives a message +//-------------------------------------------------------------------------------------- +LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) +{ + PAINTSTRUCT ps; + HDC hdc; + + switch (message) + { + case WM_PAINT: + hdc = BeginPaint(hWnd, &ps); + EndPaint(hWnd, &ps); + break; + + case WM_DESTROY: + PostQuitMessage(0); + break; + + case WM_KEYDOWN: + + switch(wParam) + { + case VK_ESCAPE: + PostQuitMessage(0); + break; + //R + case 0x52: +#ifdef _DEBUG + Oyster::Graphics::API::ReloadShaders(); +#endif + break; + } + break; + + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + + return 0; +} + diff --git a/Code/Tester/Tester.vcxproj b/Code/Tester/Tester.vcxproj new file mode 100644 index 00000000..64777849 --- /dev/null +++ b/Code/Tester/Tester.vcxproj @@ -0,0 +1,255 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {1B3BEA4C-CF75-438A-9693-60FB8444BBF3} + Win32Proj + Tester + + + + Application + true + v110 + Unicode + + + Application + true + v110 + Unicode + + + Application + false + v110 + true + Unicode + + + Application + false + v110 + true + Unicode + + + + + + + + + + + + + + + + + + + true + C:\Program Files (x86)\Visual Leak Detector\include;$(IncludePath)$(VCInstallDir)include;$(VCInstallDir)atlmfc\include; + C:\Program Files (x86)\Visual Leak Detector\lib\Win32;$(LibraryPath) + $(SolutionDir)..\Bin\Executable\ + $(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ + $(ProjectName)_$(PlatformShortName)D + + + true + C:\Program Files (x86)\Visual Leak Detector\include;$(IncludePath)$(VCInstallDir)include;$(VCInstallDir)atlmfc\include; + $(SolutionDir)..\Bin\Executable\ + $(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ + $(ProjectName)_$(PlatformShortName)D + C:\Program Files (x86)\Visual Leak Detector\lib\Win64;$(LibraryPath) + + + false + C:\Program Files (x86)\Visual Leak Detector\include;$(IncludePath)$(VCInstallDir)include;$(VCInstallDir)atlmfc\include; + C:\Program Files (x86)\Visual Leak Detector\lib\Win32;$(LibraryPath) + $(SolutionDir)..\Bin\Executable\ + $(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ + $(ProjectName)_$(PlatformShortName) + + + false + C:\Program Files (x86)\Visual Leak Detector\include;$(IncludePath)$(VCInstallDir)include;$(VCInstallDir)atlmfc\include; + $(SolutionDir)..\Bin\Executable\ + $(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ + $(ProjectName)_$(PlatformShortName) + C:\Program Files (x86)\Visual Leak Detector\lib\Win64;$(LibraryPath) + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + ..\OysterGraphics;..\OysterMath;..\Misc;%(AdditionalIncludeDirectories) + + + Windows + true + OysterGraphics_$(PlatformShortName)D.dll; + $(SolutionDir)..\Bin\DLL;%(AdditionalLibraryDirectories) + OysterGraphics_$(PlatformShortName)D.lib;%(AdditionalDependencies) + + + + + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + ..\OysterGraphics;..\OysterMath;..\Misc;%(AdditionalIncludeDirectories) + + + Windows + true + OysterGraphics_$(PlatformShortName)D.dll; + + + + + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + ..\OysterGraphics;..\OysterMath;..\Misc;%(AdditionalIncludeDirectories) + + + Windows + true + OysterGraphics_$(PlatformShortName)D.lib;%(AdditionalDependencies) + $(SolutionDir)..\Bin\DLL;%(AdditionalLibraryDirectories) + true + OysterGraphics_$(PlatformShortName)D.dll; + + + + + Level3 + + + MaxSpeed + Disabled + true + false + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + ..\OysterGraphics;..\OysterMath;..\Misc;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + OysterGraphics_$(PlatformShortName).lib;%(AdditionalDependencies) + $(SolutionDir)..\Bin\DLL;%(AdditionalLibraryDirectories) + true + OysterGraphics_$(PlatformShortName).dll; + + + + + Level3 + + + MaxSpeed + Disabled + true + false + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + ..\OysterGraphics;..\OysterMath;..\Misc;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + OysterGraphics_$(PlatformShortName).lib;%(AdditionalDependencies) + $(SolutionDir)..\Bin\DLL;%(AdditionalLibraryDirectories) + true + OysterGraphics_$(PlatformShortName).dll; + + + + + Level3 + + + Disabled + true + true + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + ..\OysterGraphics;..\OysterMath;..\Misc;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + OysterGraphics_$(PlatformShortName).lib;%(AdditionalDependencies) + $(SolutionDir)..\Bin\DLL;%(AdditionalLibraryDirectories) + true + OysterGraphics_$(PlatformShortName).dll; + + + + + + + + {2ec4dded-8f75-4c86-a10b-e1e8eb29f3ee} + + + {0ec83e64-230e-48ef-b08c-6ac9651b4f82} + false + true + false + false + false + + + {f10cbc03-9809-4cba-95d8-327c287b18ee} + + + + + + \ No newline at end of file diff --git a/Code/Tester/Tester.vcxproj.user b/Code/Tester/Tester.vcxproj.user new file mode 100644 index 00000000..2e28d6f7 --- /dev/null +++ b/Code/Tester/Tester.vcxproj.user @@ -0,0 +1,22 @@ + + + + true + + + $(OutDir) + WindowsLocalDebugger + + + $(OutDir) + WindowsLocalDebugger + + + $(OutDir) + WindowsLocalDebugger + + + $(OutDir) + WindowsLocalDebugger + + \ No newline at end of file diff --git a/Code/WindowManager/WindowShell.h b/Code/WindowManager/WindowShell.h index 86726ccf..04bb9931 100644 --- a/Code/WindowManager/WindowShell.h +++ b/Code/WindowManager/WindowShell.h @@ -7,7 +7,11 @@ #include - +struct cPOINT :public POINT +{ + cPOINT() { x=(0); y=(0); } + cPOINT(int width, int height) { x=(width); y=(height); } +}; class WindowShell { public: @@ -28,23 +32,70 @@ public: HCURSOR cursor; //!< Optional HBRUSH background; //!< Optional - WINDOW_INIT_DESC() + WINDOW_INIT_DESC( + HWND _parent = 0, + HINSTANCE _hInstance = 0, + WNDPROC _windowProcCallback = 0, + const wchar_t* _windowName = L"Window", + POINT _windowSize = cPOINT(800, 600), + POINT _windowPosition = cPOINT(0,0), + UINT _windowClassStyle = (CS_HREDRAW | CS_VREDRAW | CS_OWNDC), + UINT _windowStyle = (WS_POPUPWINDOW|WS_SYSMENU|WS_CAPTION), + HICON _icon = LoadIcon(0, IDI_APPLICATION), + HCURSOR _cursor = LoadCursor(NULL, IDC_ARROW), + HBRUSH _background = (HBRUSH)GetStockObject(BLACK_BRUSH) + ) { - parent = 0; - hInstance = NULL; - windowName = L"Window"; - windowSize.x = 800; - windowSize.y = 600; - windowPosition.x = 0; - windowPosition.y = 0; - windowProcCallback = NULL; - windowClassStyle = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; - windowStyle = WS_POPUPWINDOW|WS_SYSMENU|WS_CAPTION; - //windowStyle = WS_OVERLAPPEDWINDOW; + parent = _parent; + hInstance = _hInstance; + windowName = _windowName; + windowSize = _windowSize; + windowPosition = _windowPosition; + windowProcCallback = _windowProcCallback; + windowClassStyle = _windowClassStyle; + windowStyle = _windowStyle; + icon = _icon; + cursor = _cursor; + background = _background; + } + WINDOW_INIT_DESC( + HWND _parent, + HINSTANCE _hInstance, + WNDPROC _windowProcCallback, + const wchar_t* _windowName, + cPOINT _windowSize, + cPOINT _windowPosition + ) + { + parent = _parent; + hInstance = _hInstance; + windowName = _windowName; + windowSize = _windowSize; + windowPosition = _windowPosition; + windowProcCallback = _windowProcCallback; + windowClassStyle = (CS_HREDRAW | CS_VREDRAW | CS_OWNDC); + windowStyle = (WS_POPUPWINDOW|WS_SYSMENU|WS_CAPTION); + icon = LoadIcon(0, IDI_APPLICATION); + cursor = LoadCursor(NULL, IDC_ARROW); + background = (HBRUSH)GetStockObject(BLACK_BRUSH); + } + WINDOW_INIT_DESC( + const wchar_t* _windowName, + cPOINT _windowSize, + cPOINT _windowPosition + ) + { + parent = 0; + hInstance = 0; + windowName = _windowName; + windowSize = _windowSize; + windowPosition = _windowPosition; + windowProcCallback = 0; + windowClassStyle = (CS_HREDRAW | CS_VREDRAW | CS_OWNDC); + windowStyle = (WS_POPUPWINDOW|WS_SYSMENU|WS_CAPTION); icon = LoadIcon(0, IDI_APPLICATION); cursor = LoadCursor(NULL, IDC_ARROW); background = (HBRUSH)GetStockObject(BLACK_BRUSH); - //background = (HBRUSH)GetStockObject(BACKGROUND_BLUE);(HBRUSH)(COLOR_WINDOW+1); } };