Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f667f503e7 | |||
| 50bef9736c | |||
| 6d1ba24404 | |||
| ebd8c5e6fc | |||
| 42f9c5e1df | |||
| 3f2fcdf9e1 | |||
| 2235f307e7 | |||
| 23782ff4e3 | |||
| 2a46f82f84 | |||
| 6a32599a69 | |||
| 0ca84a8653 | |||
| 66b2d6566c | |||
| 56375d64b6 | |||
| 9608761cd5 | |||
| c1d03d1cef | |||
| 09c88c7232 | |||
| ddb93cfcf1 | |||
| 42787dcb69 | |||
| fcb17a8116 | |||
| 2dc21f64fd | |||
| f049c96df7 | |||
| d9ffa22b76 | |||
| 24654d9e17 | |||
| 7ad855348f | |||
| d833b76856 | |||
| 3232925ccd | |||
| e4ffba80aa | |||
| a4d184ca75 | |||
| 89179626be | |||
| fc381348a5 |
@@ -1,22 +1,22 @@
|
||||
_This project is currently in it's early prototype stage. You can see other versions in various branches, tagged as prototype-X._
|
||||
_This project is currently in it's early prototype stage. You can see other versions in various branches or tagged as prototype-X._
|
||||
|
||||
Tortuga is a 3/4 top down multiplayer RPG set in a large archipelago occupied by warring pirate clans. The emphasis of this game is on multiplayer competition, exploration in an open world, and solo adventuring. The game runs on a Minecraft like server system with a goal of about 50-100 players on a single server. The player characters are tied to the server where they are created, and are susceptible to permadeath: deletion of a character upon death. The servers are designed to allow a large amount of modification by the hosts.
|
||||
Tortuga is a 2D multiplayer role playing game set in a large archipelago occupied by warring pirate clans. The emphasis of this game is on multiplayer cooperation, competition, and server customization. The game runs on highly customizable server software that can support up to 150 simultaneous players or more. The player characters are tied to the server where they are created and are susceptible to permadeath: deletion of a character upon death.
|
||||
|
||||
## Libraries
|
||||
|
||||
* [SDL](http://www.libsdl.org/) - Simple DirectMedia Layer API
|
||||
* [SDL_net](http://www.libsdl.org/projects/SDL_net/) - SDL's networking extension, slightly modified. This must be installed first.
|
||||
* [SDL_net](http://www.libsdl.org/projects/SDL_net/) - SDL's networking extension. This must be installed first.
|
||||
* [Codebase](https://github.com/Ratstail91/Codebase) - generic reusable code modules
|
||||
|
||||
## Instructions
|
||||
|
||||
* This project uses C++11, which is available via GNU (or MinGW) 4.7, or Visual Studio 2012. Personally, I'm using MinGW 4.7.2.
|
||||
* I'm trying to keep this as IDE agnostic as possible, so if you use an IDE, please add it's files to .gitignore.
|
||||
* You can read more details on the GitHub wiki [here](https://github.com/Ratstail91/Tortuga/wiki).
|
||||
* You can read more details on the Tortuga wiki [here](https://github.com/Ratstail91/Tortuga/wiki).
|
||||
|
||||
## Copyright
|
||||
|
||||
Tortuga is released under the [zlib license](http://en.wikipedia.org/wiki/Zlib_License).
|
||||
The current version of Tortuga is released under the [zlib license](http://en.wikipedia.org/wiki/Zlib_License).
|
||||
|
||||
Copyright (c) 2013 Kayne Ruse
|
||||
|
||||
@@ -24,8 +24,8 @@ This software is provided 'as-is', without any express or implied warranty. In n
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#include "scene_manager.hpp"
|
||||
#include "client_application.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <chrono>
|
||||
@@ -40,29 +40,28 @@
|
||||
//Public access members
|
||||
//-------------------------
|
||||
|
||||
SceneManager::SceneManager() {
|
||||
ClientApplication::ClientApplication() {
|
||||
//
|
||||
}
|
||||
|
||||
SceneManager::~SceneManager() {
|
||||
ClientApplication::~ClientApplication() {
|
||||
UnloadScene();
|
||||
}
|
||||
|
||||
/* SceneManager::Init()
|
||||
/* ClientApplication::Init()
|
||||
* This function initializes the entire program. There are a number of things
|
||||
* that could go wrong here, which is why there is such an unusual order of
|
||||
* operations.
|
||||
* Important things to note:
|
||||
* The APIs are initiated here.
|
||||
* The global objects are created here.
|
||||
* The global objects are initialized here.
|
||||
* The game's screen is created here, based on information loaded from the config file.
|
||||
* The ConfigUtility's call to Load() also ensures that the "rsc\" folder is in the directory. It's easy to forget it.
|
||||
*/
|
||||
|
||||
void SceneManager::Init() {
|
||||
void ClientApplication::Init() {
|
||||
//load the config file
|
||||
try {
|
||||
configUtil = ServiceLocator<ConfigUtility>::Set(new ConfigUtility());
|
||||
configUtil->Load("rsc/config.cfg");
|
||||
}
|
||||
catch(std::runtime_error& e) {
|
||||
@@ -89,16 +88,11 @@ void SceneManager::Init() {
|
||||
SDL_GetVideoInfo()->vfmt->BitsPerPixel,
|
||||
flags);
|
||||
|
||||
//instanciate the remaining services
|
||||
surfaceMgr = ServiceLocator<SurfaceManager>::Set(new SurfaceManager());
|
||||
netUtil = ServiceLocator<UDPNetworkUtility>::Set(new UDPNetworkUtility());
|
||||
infoMgr = ServiceLocator<InformationManager>::Set(new InformationManager());
|
||||
|
||||
//initiate the remaining services
|
||||
//initiate the remaining singletons
|
||||
netUtil->Open(0, sizeof(Packet));
|
||||
}
|
||||
|
||||
void SceneManager::Proc() {
|
||||
void ClientApplication::Proc() {
|
||||
LoadScene(SceneList::FIRST);
|
||||
|
||||
//prepare the time system
|
||||
@@ -136,17 +130,11 @@ void SceneManager::Proc() {
|
||||
UnloadScene();
|
||||
}
|
||||
|
||||
void SceneManager::Quit() {
|
||||
//clean up the services
|
||||
void ClientApplication::Quit() {
|
||||
//clean up the singletons
|
||||
netUtil->Close();
|
||||
surfaceMgr->FreeAll();
|
||||
|
||||
//delete the services
|
||||
configUtil = ServiceLocator<ConfigUtility>::Set(nullptr);
|
||||
surfaceMgr = ServiceLocator<SurfaceManager>::Set(nullptr);
|
||||
netUtil = ServiceLocator<UDPNetworkUtility>::Set(nullptr);
|
||||
infoMgr = ServiceLocator<InformationManager>::Set(nullptr);
|
||||
|
||||
//clean up the scene
|
||||
UnloadScene();
|
||||
|
||||
@@ -159,7 +147,7 @@ void SceneManager::Quit() {
|
||||
//Private access members
|
||||
//-------------------------
|
||||
|
||||
void SceneManager::LoadScene(SceneList sceneIndex) {
|
||||
void ClientApplication::LoadScene(SceneList sceneIndex) {
|
||||
UnloadScene();
|
||||
|
||||
switch(sceneIndex) {
|
||||
@@ -189,7 +177,7 @@ void SceneManager::LoadScene(SceneList sceneIndex) {
|
||||
}
|
||||
}
|
||||
|
||||
void SceneManager::UnloadScene() {
|
||||
void ClientApplication::UnloadScene() {
|
||||
delete activeScene;
|
||||
activeScene = nullptr;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#ifndef CLIENTAPPLICATION_HPP_
|
||||
#define CLIENTAPPLICATION_HPP_
|
||||
|
||||
#include "scene_list.hpp"
|
||||
#include "base_scene.hpp"
|
||||
#include "singleton.hpp"
|
||||
#include "packet.hpp"
|
||||
#include "information_manager.hpp"
|
||||
|
||||
#include "config_utility.hpp"
|
||||
#include "surface_manager.hpp"
|
||||
#include "udp_network_utility.hpp"
|
||||
|
||||
#include "SDL/SDL.h"
|
||||
|
||||
class ClientApplication {
|
||||
public:
|
||||
/* Public access members */
|
||||
ClientApplication();
|
||||
~ClientApplication();
|
||||
|
||||
void Init();
|
||||
void Proc();
|
||||
void Quit();
|
||||
|
||||
ClientApplication(ClientApplication const&) = delete;
|
||||
ClientApplication(ClientApplication const&&) = delete;
|
||||
private:
|
||||
/* Private access members */
|
||||
void LoadScene(SceneList sceneIndex);
|
||||
void UnloadScene();
|
||||
|
||||
BaseScene* activeScene = nullptr;
|
||||
|
||||
ConfigUtility* configUtil = Singleton<ConfigUtility>::Get();
|
||||
SurfaceManager* surfaceMgr = Singleton<SurfaceManager>::Get();
|
||||
UDPNetworkUtility* netUtil = Singleton<UDPNetworkUtility>::Get();
|
||||
InformationManager* infoMgr = Singleton<InformationManager>::Get();
|
||||
};
|
||||
|
||||
#endif
|
||||
+170
-29
@@ -34,6 +34,24 @@ InWorld::InWorld() {
|
||||
cout << "entering InWorld" << endl;
|
||||
#endif
|
||||
cout << "Client Index: " << infoMgr->GetClientIndex() << endl;
|
||||
font.SetSurface(surfaceMgr->Get("font"));
|
||||
|
||||
//debugging
|
||||
Packet p;
|
||||
p.meta.type = Packet::Type::PLAYER_NEW;
|
||||
p.meta.clientIndex = infoMgr->GetClientIndex();
|
||||
|
||||
snprintf(p.playerInfo.handle, PACKET_STRING_SIZE, "%s", configUtil->CString("handle"));
|
||||
snprintf(p.playerInfo.avatar, PACKET_STRING_SIZE, "%s", configUtil->CString("avatar"));
|
||||
p.playerInfo.position = {50, 50};
|
||||
p.playerInfo.motion = {0, 0};
|
||||
|
||||
netUtil->Send(GAME_CHANNEL, &p, sizeof(Packet));
|
||||
|
||||
//request a sync
|
||||
p.meta.type = Packet::Type::SYNCHRONIZE;
|
||||
p.meta.clientIndex = infoMgr->GetClientIndex();
|
||||
netUtil->Send(GAME_CHANNEL, &p, sizeof(Packet));
|
||||
}
|
||||
|
||||
InWorld::~InWorld() {
|
||||
@@ -52,6 +70,10 @@ void InWorld::FrameStart() {
|
||||
|
||||
void InWorld::Update(double delta) {
|
||||
while(HandlePacket(popNetworkPacket()));
|
||||
|
||||
for (auto& it : playerCharacters) {
|
||||
it.second.Update(delta);
|
||||
}
|
||||
}
|
||||
|
||||
void InWorld::FrameEnd() {
|
||||
@@ -59,7 +81,15 @@ void InWorld::FrameEnd() {
|
||||
}
|
||||
|
||||
void InWorld::Render(SDL_Surface* const screen) {
|
||||
//
|
||||
ClockFrameRate();
|
||||
|
||||
for (auto& it : playerCharacters) {
|
||||
it.second.DrawTo(screen);
|
||||
}
|
||||
|
||||
//since we're using this twice, make a tmp var
|
||||
string fps = itos(GetFrameRate());
|
||||
font.DrawStringTo(fps, screen, screen->w - fps.size() * font.GetCharW(), 0);
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
@@ -85,15 +115,58 @@ void InWorld::MouseButtonUp(SDL_MouseButtonEvent const& button) {
|
||||
}
|
||||
|
||||
void InWorld::KeyDown(SDL_KeyboardEvent const& key) {
|
||||
//general
|
||||
switch(key.keysym.sym) {
|
||||
case SDLK_ESCAPE:
|
||||
ExitGame();
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
//player movement
|
||||
if (infoMgr->GetPlayerIndex() == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch(key.keysym.sym) {
|
||||
case SDLK_w:
|
||||
playerCharacters[infoMgr->GetPlayerIndex()].MoveDirection(CardinalDirection::NORTH);
|
||||
SendState();
|
||||
break;
|
||||
case SDLK_s:
|
||||
playerCharacters[infoMgr->GetPlayerIndex()].MoveDirection(CardinalDirection::SOUTH);
|
||||
SendState();
|
||||
break;
|
||||
case SDLK_a:
|
||||
playerCharacters[infoMgr->GetPlayerIndex()].MoveDirection(CardinalDirection::WEST);
|
||||
SendState();
|
||||
break;
|
||||
case SDLK_d:
|
||||
playerCharacters[infoMgr->GetPlayerIndex()].MoveDirection(CardinalDirection::EAST);
|
||||
SendState();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void InWorld::KeyUp(SDL_KeyboardEvent const& key) {
|
||||
//
|
||||
//player movement reversed
|
||||
switch(key.keysym.sym) {
|
||||
case SDLK_w:
|
||||
playerCharacters[infoMgr->GetPlayerIndex()].MoveDirection(CardinalDirection::SOUTH);
|
||||
SendState();
|
||||
break;
|
||||
case SDLK_s:
|
||||
playerCharacters[infoMgr->GetPlayerIndex()].MoveDirection(CardinalDirection::NORTH);
|
||||
SendState();
|
||||
break;
|
||||
case SDLK_a:
|
||||
playerCharacters[infoMgr->GetPlayerIndex()].MoveDirection(CardinalDirection::EAST);
|
||||
SendState();
|
||||
break;
|
||||
case SDLK_d:
|
||||
playerCharacters[infoMgr->GetPlayerIndex()].MoveDirection(CardinalDirection::WEST);
|
||||
SendState();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
@@ -102,45 +175,46 @@ void InWorld::KeyUp(SDL_KeyboardEvent const& key) {
|
||||
|
||||
int InWorld::HandlePacket(Packet p) {
|
||||
switch(p.meta.type) {
|
||||
case PacketType::NONE:
|
||||
case Packet::Type::NONE:
|
||||
//DO NOTHING
|
||||
return 0;
|
||||
break;
|
||||
case PacketType::PING:
|
||||
case Packet::Type::PING:
|
||||
//quick pong
|
||||
p.meta.type = PacketType::PONG;
|
||||
p.meta.type = Packet::Type::PONG;
|
||||
p.meta.clientIndex = infoMgr->GetClientIndex();
|
||||
netUtil->Send(&p.meta.address, &p, sizeof(Packet));
|
||||
break;
|
||||
case PacketType::PONG:
|
||||
case Packet::Type::PONG:
|
||||
//
|
||||
break;
|
||||
// case PacketType::BROADCAST_REQUEST:
|
||||
// case Packet::Type::BROADCAST_REQUEST:
|
||||
// //
|
||||
// break;
|
||||
// case PacketType::BROADCAST_RESPONSE:
|
||||
// case Packet::Type::BROADCAST_RESPONSE:
|
||||
// //
|
||||
// break;
|
||||
// case PacketType::JOIN_REQUEST:
|
||||
// case Packet::Type::JOIN_REQUEST:
|
||||
// //
|
||||
// break;
|
||||
// case PacketType::JOIN_RESPONSE:
|
||||
// case Packet::Type::JOIN_RESPONSE:
|
||||
// //
|
||||
// break;
|
||||
case PacketType::DISCONNECT:
|
||||
HandleDisconnection(p.disconnect);
|
||||
case Packet::Type::DISCONNECT:
|
||||
HandleDisconnection(p);
|
||||
break;
|
||||
// case PacketType::SYNCHRONIZE:
|
||||
// //
|
||||
// break;
|
||||
// case PacketType::PLAYER_NEW:
|
||||
// //
|
||||
// break;
|
||||
// case PacketType::PLAYER_DELETE:
|
||||
// //
|
||||
// break;
|
||||
// case PacketType::PLAYER_MOVE:
|
||||
// case Packet::Type::SYNCHRONIZE:
|
||||
// //
|
||||
// break;
|
||||
case Packet::Type::PLAYER_NEW:
|
||||
AddPlayer(p);
|
||||
break;
|
||||
case Packet::Type::PLAYER_DELETE:
|
||||
RemovePlayer(p);
|
||||
break;
|
||||
case Packet::Type::PLAYER_UPDATE:
|
||||
UpdatePlayer(p);
|
||||
break;
|
||||
default:
|
||||
throw(runtime_error("Failed to recognize the packet type: " + itos(int(p.meta.type))));
|
||||
}
|
||||
@@ -148,26 +222,93 @@ int InWorld::HandlePacket(Packet p) {
|
||||
}
|
||||
|
||||
void InWorld::Disconnect() {
|
||||
//disconnect
|
||||
Packet p;
|
||||
p.meta.type = PacketType::DISCONNECT;
|
||||
p.disconnect.clientIndex = infoMgr->GetClientIndex();
|
||||
netUtil->Send(GAME_CHANNEL, reinterpret_cast<void*>(&p), sizeof(Packet));
|
||||
|
||||
//delete the player
|
||||
p.meta.type = Packet::Type::PLAYER_DELETE;
|
||||
p.meta.clientIndex = infoMgr->GetClientIndex();
|
||||
p.playerInfo.index = infoMgr->GetPlayerIndex();
|
||||
netUtil->Send(GAME_CHANNEL, &p, sizeof(Packet));
|
||||
|
||||
//disconnect
|
||||
p.meta.type = Packet::Type::DISCONNECT;
|
||||
p.meta.clientIndex = infoMgr->GetClientIndex();
|
||||
netUtil->Send(GAME_CHANNEL, &p, sizeof(Packet));
|
||||
|
||||
netUtil->Unbind(GAME_CHANNEL);
|
||||
endQueueThread();
|
||||
|
||||
//reset the client
|
||||
infoMgr->ResetClientIndex();
|
||||
infoMgr->ResetPlayerIndex();
|
||||
}
|
||||
|
||||
void InWorld::ExitGame() {
|
||||
Disconnect();
|
||||
SetNextScene(SceneList::MAINMENU);
|
||||
endQueueThread();
|
||||
cout << "The game session has ended" << endl;
|
||||
}
|
||||
|
||||
void InWorld::HandleDisconnection(::Disconnect& disconnect) {
|
||||
void InWorld::HandleDisconnection(Packet& disconnect) {
|
||||
Disconnect();
|
||||
SetNextScene(SceneList::MAINMENU);
|
||||
endQueueThread();
|
||||
cout << "You have been disconnected" << endl;
|
||||
}
|
||||
|
||||
void InWorld::AddPlayer(Packet& p) {
|
||||
if (playerCharacters.find(p.playerInfo.index) != playerCharacters.end()) {
|
||||
throw(runtime_error("Duplicate players detected"));
|
||||
}
|
||||
|
||||
//position
|
||||
playerCharacters[p.playerInfo.index].SetPosition(p.playerInfo.position);
|
||||
playerCharacters[p.playerInfo.index].SetMotion(p.playerInfo.motion);
|
||||
|
||||
//sprite
|
||||
playerCharacters[p.playerInfo.index].GetSprite()->SetSurface(surfaceMgr->Get(p.playerInfo.avatar), 32, 48);
|
||||
playerCharacters[p.playerInfo.index].FaceDirection();
|
||||
|
||||
//is it this player?
|
||||
if (p.meta.clientIndex == infoMgr->GetClientIndex()) {
|
||||
infoMgr->SetPlayerIndex(p.playerInfo.index);
|
||||
}
|
||||
|
||||
//debugging
|
||||
cout << "New player, index " << p.playerInfo.index << endl;
|
||||
}
|
||||
|
||||
void InWorld::RemovePlayer(Packet& p) {
|
||||
if (playerCharacters.find(p.playerInfo.index) == playerCharacters.end()) {
|
||||
throw(runtime_error("Player to delete not found"));
|
||||
}
|
||||
|
||||
playerCharacters.erase(p.playerInfo.index);
|
||||
}
|
||||
|
||||
void InWorld::UpdatePlayer(Packet& p) {
|
||||
if (playerCharacters.find(p.playerInfo.index) == playerCharacters.end()) {
|
||||
AddPlayer(p);
|
||||
return;
|
||||
}
|
||||
|
||||
playerCharacters[p.playerInfo.index].SetPosition(p.playerInfo.position);
|
||||
playerCharacters[p.playerInfo.index].SetMotion(p.playerInfo.motion);
|
||||
playerCharacters[p.playerInfo.index].FaceDirection();
|
||||
}
|
||||
|
||||
void InWorld::SendState() {
|
||||
//send the state of this player's character
|
||||
if (infoMgr->GetPlayerIndex() == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
Packet p;
|
||||
p.meta.type = Packet::Type::PLAYER_UPDATE;
|
||||
p.meta.clientIndex = infoMgr->GetClientIndex();
|
||||
p.playerInfo.index = infoMgr->GetPlayerIndex();
|
||||
p.playerInfo.position = playerCharacters[infoMgr->GetPlayerIndex()].GetPosition();
|
||||
p.playerInfo.motion = playerCharacters[infoMgr->GetPlayerIndex()].GetMotion();
|
||||
|
||||
netUtil->Send(GAME_CHANNEL, &p, sizeof(Packet));
|
||||
}
|
||||
|
||||
+23
-9
@@ -23,17 +23,23 @@
|
||||
#define INWORLD_HPP_
|
||||
|
||||
#include "base_scene.hpp"
|
||||
|
||||
#include "utilities.hpp"
|
||||
#include "defines.hpp"
|
||||
#include "service_locator.hpp"
|
||||
#include "packet_type.hpp"
|
||||
#include "singleton.hpp"
|
||||
#include "packet.hpp"
|
||||
#include "network_queue.hpp"
|
||||
#include "information_manager.hpp"
|
||||
#include "player_character.hpp"
|
||||
|
||||
#include "config_utility.hpp"
|
||||
#include "surface_manager.hpp"
|
||||
#include "udp_network_utility.hpp"
|
||||
#include "button.hpp"
|
||||
#include "raster_font.hpp"
|
||||
#include "frame_rate.hpp"
|
||||
|
||||
#include <map>
|
||||
|
||||
class InWorld : public BaseScene {
|
||||
public:
|
||||
@@ -57,19 +63,27 @@ protected:
|
||||
void KeyUp(SDL_KeyboardEvent const&);
|
||||
|
||||
//Utilities
|
||||
int HandlePacket(Packet p);
|
||||
int HandlePacket(Packet);
|
||||
void Disconnect();
|
||||
void ExitGame();
|
||||
void HandleDisconnection(::Disconnect&);
|
||||
|
||||
void HandleDisconnection(Packet&);
|
||||
|
||||
void AddPlayer(Packet&);
|
||||
void RemovePlayer(Packet&);
|
||||
void UpdatePlayer(Packet&);
|
||||
|
||||
void SendState();
|
||||
|
||||
//services
|
||||
ConfigUtility* configUtil = ServiceLocator<ConfigUtility>::Get();
|
||||
SurfaceManager* surfaceMgr = ServiceLocator<SurfaceManager>::Get();
|
||||
UDPNetworkUtility* netUtil = ServiceLocator<UDPNetworkUtility>::Get();
|
||||
InformationManager* infoMgr = ServiceLocator<InformationManager>::Get();
|
||||
ConfigUtility* configUtil = Singleton<ConfigUtility>::Get();
|
||||
SurfaceManager* surfaceMgr = Singleton<SurfaceManager>::Get();
|
||||
UDPNetworkUtility* netUtil = Singleton<UDPNetworkUtility>::Get();
|
||||
InformationManager* infoMgr = Singleton<InformationManager>::Get();
|
||||
|
||||
//members
|
||||
//...
|
||||
RasterFont font;
|
||||
std::map<int, PlayerCharacter> playerCharacters;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,8 +27,14 @@ public:
|
||||
int SetClientIndex(int i) { return clientIndex = i; }
|
||||
int GetClientIndex() { return clientIndex; }
|
||||
void ResetClientIndex() { clientIndex = -1; }
|
||||
|
||||
//one player at a time
|
||||
int SetPlayerIndex(int i) { return playerIndex = i; }
|
||||
int GetPlayerIndex() { return playerIndex; }
|
||||
void ResetPlayerIndex() { playerIndex = -1; }
|
||||
private:
|
||||
int clientIndex = -1;
|
||||
int playerIndex = -1;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+21
-21
@@ -157,43 +157,43 @@ void Lobby::KeyUp(SDL_KeyboardEvent const& key) {
|
||||
|
||||
int Lobby::HandlePacket(Packet p) {
|
||||
switch(p.meta.type) {
|
||||
case PacketType::NONE:
|
||||
case Packet::Type::NONE:
|
||||
//DO NOTHING
|
||||
return 0;
|
||||
break;
|
||||
case PacketType::PING:
|
||||
case Packet::Type::PING:
|
||||
//quick pong
|
||||
p.meta.type = PacketType::PONG;
|
||||
p.meta.type = Packet::Type::PONG;
|
||||
netUtil->Send(&p.meta.address, &p, sizeof(Packet));
|
||||
break;
|
||||
case PacketType::PONG:
|
||||
case Packet::Type::PONG:
|
||||
//
|
||||
break;
|
||||
// case PacketType::BROADCAST_REQUEST:
|
||||
// case Packet::Type::BROADCAST_REQUEST:
|
||||
// //
|
||||
// break;
|
||||
case PacketType::BROADCAST_RESPONSE:
|
||||
PushServer(p.broadcastResponse);
|
||||
case Packet::Type::BROADCAST_RESPONSE:
|
||||
PushServer(p);
|
||||
break;
|
||||
// case PacketType::JOIN_REQUEST:
|
||||
// case Packet::Type::JOIN_REQUEST:
|
||||
// //
|
||||
// break;
|
||||
case PacketType::JOIN_RESPONSE:
|
||||
BeginGame(p.joinResponse);
|
||||
case Packet::Type::JOIN_RESPONSE:
|
||||
BeginGame(p);
|
||||
break;
|
||||
// case PacketType::DISCONNECT:
|
||||
// case Packet::Type::DISCONNECT:
|
||||
// //
|
||||
// break;
|
||||
// case PacketType::SYNCHRONIZE:
|
||||
// case Packet::Type::SYNCHRONIZE:
|
||||
// //
|
||||
// break;
|
||||
// case PacketType::PLAYER_NEW:
|
||||
// case Packet::Type::PLAYER_NEW:
|
||||
// //
|
||||
// break;
|
||||
// case PacketType::PLAYER_DELETE:
|
||||
// case Packet::Type::PLAYER_DELETE:
|
||||
// //
|
||||
// break;
|
||||
// case PacketType::PLAYER_MOVE:
|
||||
// case Packet::Type::PLAYER_UPDATE:
|
||||
// //
|
||||
// break;
|
||||
default:
|
||||
@@ -204,14 +204,14 @@ int Lobby::HandlePacket(Packet p) {
|
||||
|
||||
void Lobby::BroadcastNetwork() {
|
||||
Packet p;
|
||||
p.meta.type = PacketType::BROADCAST_REQUEST;
|
||||
p.meta.type = Packet::Type::BROADCAST_REQUEST;
|
||||
netUtil->Send("255.255.255.255", configUtil->Int("server.port"), &p, sizeof(Packet));
|
||||
serverList.clear();
|
||||
}
|
||||
|
||||
void Lobby::PushServer(BroadcastResponse& bcast) {
|
||||
void Lobby::PushServer(Packet& bcast) {
|
||||
ServerEntry entry;
|
||||
entry.name = bcast.name;
|
||||
entry.name = bcast.serverInfo.name;
|
||||
entry.address = bcast.meta.address;
|
||||
serverList.push_back(entry);
|
||||
}
|
||||
@@ -222,13 +222,13 @@ void Lobby::ConnectToServer(ServerEntry* server) {
|
||||
throw(runtime_error("No server received"));
|
||||
}
|
||||
Packet p;
|
||||
p.meta.type = PacketType::JOIN_REQUEST;
|
||||
p.meta.type = Packet::Type::JOIN_REQUEST;
|
||||
netUtil->Send(&server->address, reinterpret_cast<void*>(&p), sizeof(Packet));
|
||||
}
|
||||
|
||||
void Lobby::BeginGame(JoinResponse& response) {
|
||||
void Lobby::BeginGame(Packet& response) {
|
||||
//should be downloading the resources here as well
|
||||
infoMgr->SetClientIndex(response.clientIndex);
|
||||
infoMgr->SetClientIndex(response.meta.clientIndex);
|
||||
netUtil->Bind(&response.meta.address, GAME_CHANNEL);
|
||||
SetNextScene(SceneList::INWORLD);
|
||||
}
|
||||
+13
-14
@@ -23,9 +23,13 @@
|
||||
#define LOBBY_HPP_
|
||||
|
||||
#include "base_scene.hpp"
|
||||
|
||||
#include "utilities.hpp"
|
||||
#include "defines.hpp"
|
||||
#include "service_locator.hpp"
|
||||
#include "packet_type.hpp"
|
||||
#include "singleton.hpp"
|
||||
|
||||
#include "server_entry.hpp"
|
||||
#include "packet.hpp"
|
||||
#include "network_queue.hpp"
|
||||
#include "information_manager.hpp"
|
||||
|
||||
@@ -38,11 +42,6 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
struct ServerEntry {
|
||||
std::string name;
|
||||
IPaddress address;
|
||||
};
|
||||
|
||||
class Lobby : public BaseScene {
|
||||
public:
|
||||
//Public access members
|
||||
@@ -64,17 +63,17 @@ protected:
|
||||
void KeyUp(SDL_KeyboardEvent const&);
|
||||
|
||||
//utilities
|
||||
int HandlePacket(Packet p);
|
||||
int HandlePacket(Packet);
|
||||
void BroadcastNetwork();
|
||||
void PushServer(BroadcastResponse&);
|
||||
void PushServer(Packet&);
|
||||
void ConnectToServer(ServerEntry*);
|
||||
void BeginGame(JoinResponse&);
|
||||
void BeginGame(Packet&);
|
||||
|
||||
//services
|
||||
ConfigUtility* configUtil = ServiceLocator<ConfigUtility>::Get();
|
||||
SurfaceManager* surfaceMgr = ServiceLocator<SurfaceManager>::Get();
|
||||
UDPNetworkUtility* netUtil = ServiceLocator<UDPNetworkUtility>::Get();
|
||||
InformationManager* infoMgr = ServiceLocator<InformationManager>::Get();
|
||||
ConfigUtility* configUtil = Singleton<ConfigUtility>::Get();
|
||||
SurfaceManager* surfaceMgr = Singleton<SurfaceManager>::Get();
|
||||
UDPNetworkUtility* netUtil = Singleton<UDPNetworkUtility>::Get();
|
||||
InformationManager* infoMgr = Singleton<InformationManager>::Get();
|
||||
|
||||
//members
|
||||
Button refreshButton;
|
||||
|
||||
+2
-2
@@ -19,7 +19,7 @@
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#include "scene_manager.hpp"
|
||||
#include "client_application.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
@@ -31,7 +31,7 @@ int main(int, char**) {
|
||||
cout << "Beginning program" << endl;
|
||||
#endif
|
||||
try {
|
||||
SceneManager app;
|
||||
ClientApplication app;
|
||||
app.Init();
|
||||
app.Proc();
|
||||
app.Quit();
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#define MAINMENU_HPP_
|
||||
|
||||
#include "base_scene.hpp"
|
||||
#include "service_locator.hpp"
|
||||
#include "singleton.hpp"
|
||||
|
||||
#include "surface_manager.hpp"
|
||||
#include "button.hpp"
|
||||
@@ -47,7 +47,7 @@ protected:
|
||||
void MouseButtonUp(SDL_MouseButtonEvent const&);
|
||||
void KeyDown(SDL_KeyboardEvent const&);
|
||||
|
||||
SurfaceManager* surfaceMgr = ServiceLocator<SurfaceManager>::Get();
|
||||
SurfaceManager* surfaceMgr = Singleton<SurfaceManager>::Get();
|
||||
|
||||
Button startButton;
|
||||
Button optionsButton;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#define OPTIONSCREEN_HPP_
|
||||
|
||||
#include "base_scene.hpp"
|
||||
#include "service_locator.hpp"
|
||||
#include "singleton.hpp"
|
||||
|
||||
#include "surface_manager.hpp"
|
||||
#include "button.hpp"
|
||||
@@ -44,7 +44,7 @@ protected:
|
||||
void MouseButtonUp(SDL_MouseButtonEvent const&);
|
||||
void KeyDown(SDL_KeyboardEvent const&);
|
||||
|
||||
SurfaceManager* surfaceMgr = ServiceLocator<SurfaceManager>::Get();
|
||||
SurfaceManager* surfaceMgr = Singleton<SurfaceManager>::Get();
|
||||
Button backButton;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#include "player_character.hpp"
|
||||
|
||||
void PlayerCharacter::Update(double delta) {
|
||||
if (limitSpeed) {
|
||||
constexpr double d = 1.0/sqrt(2);
|
||||
position += motion * delta * d;
|
||||
}
|
||||
else {
|
||||
position += motion * delta;
|
||||
}
|
||||
sprite.Update(delta);
|
||||
}
|
||||
|
||||
void PlayerCharacter::MoveDirection(CardinalDirection cd) {
|
||||
//shift the movement in this direction
|
||||
switch(cd) {
|
||||
case CardinalDirection::NORTH:
|
||||
if (motion.y >= 0) {
|
||||
motion.y -= WALKING_SPEED;
|
||||
}
|
||||
break;
|
||||
case CardinalDirection::SOUTH:
|
||||
if (motion.y <= 0) {
|
||||
motion.y += WALKING_SPEED;
|
||||
}
|
||||
break;
|
||||
case CardinalDirection::WEST:
|
||||
if (motion.x >= 0) {
|
||||
motion.x -= WALKING_SPEED;
|
||||
}
|
||||
break;
|
||||
case CardinalDirection::EAST:
|
||||
if (motion.x <= 0) {
|
||||
motion.x += WALKING_SPEED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
//face the correct direction
|
||||
FaceDirection();
|
||||
}
|
||||
|
||||
void PlayerCharacter::FaceDirection(CardinalDirection cd) {
|
||||
switch(cd) {
|
||||
case CardinalDirection::NORTH:
|
||||
sprite.SetCurrentStrip(1);
|
||||
break;
|
||||
case CardinalDirection::SOUTH:
|
||||
sprite.SetCurrentStrip(0);
|
||||
break;
|
||||
case CardinalDirection::WEST:
|
||||
sprite.SetCurrentStrip(2);
|
||||
break;
|
||||
case CardinalDirection::EAST:
|
||||
sprite.SetCurrentStrip(3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerCharacter::FaceDirection() {
|
||||
//base the direction on the character's movement
|
||||
if (motion.y < 0) {
|
||||
FaceDirection(CardinalDirection::NORTH);
|
||||
}
|
||||
if (motion.y > 0) {
|
||||
FaceDirection(CardinalDirection::SOUTH);
|
||||
}
|
||||
if (motion.x < 0) {
|
||||
FaceDirection(CardinalDirection::WEST);
|
||||
}
|
||||
if (motion.x > 0) {
|
||||
FaceDirection(CardinalDirection::EAST);
|
||||
}
|
||||
CheckSpeed();
|
||||
}
|
||||
|
||||
void PlayerCharacter::CheckSpeed() {
|
||||
//diagonal
|
||||
if (motion.x != 0 && motion.y != 0) {
|
||||
sprite.SetInterval(0.1);
|
||||
limitSpeed = true;
|
||||
}
|
||||
//cardinal
|
||||
else if (motion != 0) {
|
||||
sprite.SetInterval(0.1);
|
||||
limitSpeed = false;
|
||||
}
|
||||
//not moving
|
||||
else {
|
||||
sprite.SetInterval(0);
|
||||
sprite.SetCurrentFrame(0);
|
||||
limitSpeed = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#ifndef PLAYERCHARACTER_HPP_
|
||||
#define PLAYERCHARACTER_HPP_
|
||||
|
||||
#include "vector2.hpp"
|
||||
#include "sprite_sheet.hpp"
|
||||
#include "defines.hpp"
|
||||
|
||||
class PlayerCharacter {
|
||||
public:
|
||||
PlayerCharacter() = default;
|
||||
~PlayerCharacter() = default;
|
||||
|
||||
void Update(double delta);
|
||||
|
||||
void MoveDirection(CardinalDirection);
|
||||
void FaceDirection(CardinalDirection);
|
||||
void FaceDirection();
|
||||
|
||||
void DrawTo(SDL_Surface* const dest) { sprite.DrawTo(dest, position.x, position.y); }
|
||||
|
||||
//accessors and mutators
|
||||
Vector2 SetPosition(Vector2 v) { return position = v; }
|
||||
Vector2 ShiftPosition(Vector2 v) { return position += v; }
|
||||
Vector2 GetPosition() { return position; }
|
||||
|
||||
Vector2 SetMotion(Vector2 v) { return motion = v; }
|
||||
Vector2 ShiftMotion(Vector2 v) { return motion += v; }
|
||||
Vector2 GetMotion() { return motion; }
|
||||
|
||||
SpriteSheet* GetSprite() { return &sprite; }
|
||||
private:
|
||||
void CheckSpeed();
|
||||
|
||||
Vector2 position;
|
||||
Vector2 motion;
|
||||
SpriteSheet sprite;
|
||||
|
||||
//for moving diagonal
|
||||
bool limitSpeed = false;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -59,7 +59,7 @@ void SplashScreen::RunFrame(double delta) {
|
||||
LoadResources();
|
||||
}
|
||||
|
||||
if (Clock::now() - start > std::chrono::duration<int>(1)) {
|
||||
if (std::chrono::steady_clock::now() - start > std::chrono::duration<int>(1)) {
|
||||
SetNextScene(SceneList::MAINMENU);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,7 @@
|
||||
#define SPLASHSCREEN_HPP_
|
||||
|
||||
#include "base_scene.hpp"
|
||||
#include "defines.hpp"
|
||||
#include "service_locator.hpp"
|
||||
#include "singleton.hpp"
|
||||
|
||||
#include "config_utility.hpp"
|
||||
#include "surface_manager.hpp"
|
||||
@@ -45,10 +44,10 @@ protected:
|
||||
void LoadResources();
|
||||
|
||||
bool loaded = false;
|
||||
ConfigUtility* configUtil = ServiceLocator<ConfigUtility>::Get();
|
||||
SurfaceManager* surfaceMgr = ServiceLocator<SurfaceManager>::Get();
|
||||
ConfigUtility* configUtil = Singleton<ConfigUtility>::Get();
|
||||
SurfaceManager* surfaceMgr = Singleton<SurfaceManager>::Get();
|
||||
Image logo;
|
||||
Clock::time_point start = Clock::now();
|
||||
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#include "base_scene.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
//-------------------------
|
||||
//Static declarations
|
||||
//-------------------------
|
||||
|
||||
SDL_Surface* BaseScene::screen = nullptr;
|
||||
|
||||
//-------------------------
|
||||
//Public access members
|
||||
//-------------------------
|
||||
|
||||
BaseScene::BaseScene() {
|
||||
nextScene = SceneList::CONTINUE;
|
||||
}
|
||||
|
||||
BaseScene::~BaseScene() {
|
||||
//
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
//Program control
|
||||
//-------------------------
|
||||
|
||||
SDL_Surface* BaseScene::SetScreen(int w, int h, int bpp, Uint32 flags) {
|
||||
if (!bpp) {
|
||||
bpp = SDL_GetVideoInfo()->vfmt->BitsPerPixel;
|
||||
}
|
||||
|
||||
screen = SDL_SetVideoMode(w, h, bpp, flags);
|
||||
|
||||
if (!screen) {
|
||||
throw(std::runtime_error("Failed to create the screen surface"));
|
||||
}
|
||||
|
||||
return screen;
|
||||
}
|
||||
|
||||
SDL_Surface* BaseScene::GetScreen() {
|
||||
return screen;
|
||||
}
|
||||
|
||||
SceneList BaseScene::SetNextScene(SceneList sceneIndex) {
|
||||
return nextScene = sceneIndex;
|
||||
}
|
||||
|
||||
SceneList BaseScene::GetNextScene() const {
|
||||
return nextScene;
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
//Frame loop
|
||||
//-------------------------
|
||||
|
||||
void BaseScene::RunFrame(double delta) {
|
||||
FrameStart();
|
||||
HandleEvents();
|
||||
Update(delta);
|
||||
FrameEnd();
|
||||
}
|
||||
|
||||
void BaseScene::RenderFrame() {
|
||||
SDL_FillRect(screen, 0, 0);
|
||||
Render(screen);
|
||||
SDL_Flip(screen);
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
//Event handlers
|
||||
//-------------------------
|
||||
|
||||
void BaseScene::HandleEvents() {
|
||||
SDL_Event event;
|
||||
|
||||
while(SDL_PollEvent(&event)) {
|
||||
switch(event.type) {
|
||||
case SDL_QUIT:
|
||||
QuitEvent();
|
||||
break;
|
||||
|
||||
case SDL_VIDEORESIZE:
|
||||
SetScreen(event.resize.w, event.resize.h, 0, screen->flags);
|
||||
break;
|
||||
|
||||
case SDL_MOUSEMOTION:
|
||||
MouseMotion(event.motion);
|
||||
break;
|
||||
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
MouseButtonDown(event.button);
|
||||
break;
|
||||
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
MouseButtonUp(event.button);
|
||||
break;
|
||||
|
||||
case SDL_KEYDOWN:
|
||||
KeyDown(event.key);
|
||||
break;
|
||||
|
||||
case SDL_KEYUP:
|
||||
KeyUp(event.key);
|
||||
break;
|
||||
|
||||
#ifdef USE_EVENT_JOYSTICK
|
||||
//TODO: joystick/gamepad support
|
||||
#endif
|
||||
|
||||
#ifdef USE_EVENT_UNKNOWN
|
||||
default:
|
||||
UnknownEvent(event);
|
||||
break;
|
||||
#endif
|
||||
}//switch
|
||||
}//while
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#ifndef BASESCENE_HPP_
|
||||
#define BASESCENE_HPP_
|
||||
|
||||
#include "scene_list.hpp"
|
||||
|
||||
#include "SDL/SDL.h"
|
||||
|
||||
class BaseScene {
|
||||
public:
|
||||
/* Public access members */
|
||||
BaseScene();
|
||||
virtual ~BaseScene();
|
||||
|
||||
/* Program control */
|
||||
static SDL_Surface* SetScreen(int w, int h, int bpp = 0, Uint32 flags = SDL_HWSURFACE|SDL_DOUBLEBUF);
|
||||
static SDL_Surface* GetScreen();
|
||||
|
||||
SceneList SetNextScene(SceneList sceneIndex);
|
||||
SceneList GetNextScene() const;
|
||||
|
||||
/* Frame loop */
|
||||
virtual void RunFrame(double delta);
|
||||
virtual void RenderFrame();
|
||||
|
||||
protected:
|
||||
virtual void FrameStart() {}
|
||||
virtual void HandleEvents();
|
||||
virtual void Update(double delta) {}
|
||||
virtual void FrameEnd() {}
|
||||
virtual void Render(SDL_Surface* const screen) {}
|
||||
|
||||
/* Event handlers */
|
||||
virtual void QuitEvent() { SetNextScene(SceneList::QUIT); }
|
||||
virtual void MouseMotion(SDL_MouseMotionEvent const&) {}
|
||||
virtual void MouseButtonDown(SDL_MouseButtonEvent const&) {}
|
||||
virtual void MouseButtonUp(SDL_MouseButtonEvent const&) {}
|
||||
virtual void KeyDown(SDL_KeyboardEvent const&) {}
|
||||
virtual void KeyUp(SDL_KeyboardEvent const&) {}
|
||||
|
||||
#ifdef USE_EVENT_JOYSTICK
|
||||
//TODO: joystick/gamepad support
|
||||
#endif
|
||||
|
||||
#ifdef USE_EVENT_UNKNOWN
|
||||
virtual void UnknownEvent(SDL_Event const&) {}
|
||||
#endif
|
||||
|
||||
private:
|
||||
static SDL_Surface* screen;
|
||||
SceneList nextScene;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,118 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#include "editor_application.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <chrono>
|
||||
|
||||
//-------------------------
|
||||
//Scene headers
|
||||
//-------------------------
|
||||
|
||||
//Add the custom scene headers here
|
||||
#include "map_editor.hpp"
|
||||
|
||||
//-------------------------
|
||||
//Public access members
|
||||
//-------------------------
|
||||
|
||||
EditorApplication::EditorApplication() {
|
||||
//
|
||||
}
|
||||
|
||||
EditorApplication::~EditorApplication() {
|
||||
UnloadScene();
|
||||
}
|
||||
|
||||
void EditorApplication::Init() {
|
||||
if (SDL_Init(SDL_INIT_VIDEO))
|
||||
throw(std::runtime_error("Failed to initialize SDL"));
|
||||
|
||||
BaseScene::SetScreen(800, 600);
|
||||
}
|
||||
|
||||
void EditorApplication::Proc() {
|
||||
LoadScene(SceneList::FIRST);
|
||||
|
||||
//prepare the time system
|
||||
typedef std::chrono::high_resolution_clock Clock;
|
||||
|
||||
Clock::duration delta(16 * Clock::duration::period::den / std::milli::den);
|
||||
Clock::time_point simTime = Clock::now();
|
||||
Clock::time_point realTime;
|
||||
|
||||
//The main loop
|
||||
while(activeScene->GetNextScene() != SceneList::QUIT) {
|
||||
//switch scenes when necessary
|
||||
if (activeScene->GetNextScene() != SceneList::CONTINUE) {
|
||||
LoadScene(activeScene->GetNextScene());
|
||||
continue;
|
||||
}
|
||||
|
||||
//update the current time
|
||||
realTime = Clock::now();
|
||||
|
||||
//simulate game time
|
||||
while (simTime < realTime) {
|
||||
//call each user defined function
|
||||
activeScene->RunFrame(double(delta.count()) / Clock::duration::period::den);
|
||||
simTime += delta;
|
||||
}
|
||||
|
||||
//draw the game to the screen
|
||||
activeScene->RenderFrame();
|
||||
|
||||
//give the computer a break
|
||||
SDL_Delay(10);
|
||||
}
|
||||
|
||||
UnloadScene();
|
||||
}
|
||||
|
||||
void EditorApplication::Quit() {
|
||||
UnloadScene();
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
//Private access members
|
||||
//-------------------------
|
||||
|
||||
void EditorApplication::LoadScene(SceneList sceneIndex) {
|
||||
UnloadScene();
|
||||
|
||||
switch(sceneIndex) {
|
||||
//add scene creation calls here
|
||||
case SceneList::FIRST:
|
||||
case SceneList::MAPEDITOR:
|
||||
activeScene = new MapEditor();
|
||||
break;
|
||||
|
||||
default:
|
||||
throw(std::logic_error("Failed to recognize the scene index"));
|
||||
}
|
||||
}
|
||||
|
||||
void EditorApplication::UnloadScene() {
|
||||
delete activeScene;
|
||||
activeScene = nullptr;
|
||||
}
|
||||
@@ -19,42 +19,32 @@
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#ifndef SCENEMANAGER_HPP_
|
||||
#define SCENEMANAGER_HPP_
|
||||
#ifndef EDITORAPPLICATION_HPP_
|
||||
#define EDITORAPPLICATION_HPP_
|
||||
|
||||
#include "scene_list.hpp"
|
||||
#include "base_scene.hpp"
|
||||
#include "service_locator.hpp"
|
||||
#include "packet_type.hpp"
|
||||
#include "information_manager.hpp"
|
||||
|
||||
#include "config_utility.hpp"
|
||||
#include "surface_manager.hpp"
|
||||
#include "udp_network_utility.hpp"
|
||||
|
||||
#include "SDL/SDL.h"
|
||||
|
||||
class SceneManager {
|
||||
class EditorApplication {
|
||||
public:
|
||||
/* Public access members */
|
||||
SceneManager();
|
||||
~SceneManager();
|
||||
EditorApplication();
|
||||
~EditorApplication();
|
||||
|
||||
void Init();
|
||||
void Proc();
|
||||
void Quit();
|
||||
|
||||
EditorApplication(EditorApplication const&) = delete;
|
||||
EditorApplication(EditorApplication const&&) = delete;
|
||||
private:
|
||||
/* Private access members */
|
||||
void LoadScene(SceneList sceneIndex);
|
||||
void UnloadScene();
|
||||
|
||||
BaseScene* activeScene = nullptr;
|
||||
|
||||
ConfigUtility* configUtil = nullptr;
|
||||
SurfaceManager* surfaceMgr = nullptr;
|
||||
UDPNetworkUtility* netUtil = nullptr;
|
||||
InformationManager* infoMgr = nullptr;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,47 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#include "editor_application.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(int, char**) {
|
||||
#ifdef DEBUG
|
||||
cout << "Beginning program" << endl;
|
||||
#endif
|
||||
try {
|
||||
EditorApplication app;
|
||||
app.Init();
|
||||
app.Proc();
|
||||
app.Quit();
|
||||
}
|
||||
catch(exception& e) {
|
||||
cerr << "Fatal error: " << e.what() << endl;
|
||||
return 1;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
cout << "Clean exit" << endl;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#config
|
||||
LIBDIR=../libs
|
||||
LOCALLIBS=$(LIBDIR)/out/libCodebase.a $(LIBDIR)/out/libCommon.a
|
||||
LIB=$(LOCALLIBS) -lmingw32 -lSDLmain -lSDL
|
||||
INCLUDES=$(LIBDIR)/Codebase $(LIBDIR)/common
|
||||
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
|
||||
|
||||
#source
|
||||
SRC=$(wildcard *.cpp)
|
||||
|
||||
#objects
|
||||
OBJDIR=obj
|
||||
OBJ=$(addprefix $(OBJDIR)/,$(SRC:.cpp=.o))
|
||||
|
||||
#output
|
||||
OUTDIR=../out
|
||||
OUT=$(addprefix $(OUTDIR)/,editor)
|
||||
|
||||
#targets
|
||||
all: $(OBJ) $(OUT)
|
||||
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIB)
|
||||
|
||||
$(OBJ): | $(OBJDIR)
|
||||
|
||||
$(OUT): | $(OUTDIR)
|
||||
|
||||
$(OBJDIR):
|
||||
mkdir $(OBJDIR)
|
||||
|
||||
$(OUTDIR):
|
||||
mkdir $(OUTDIR)
|
||||
|
||||
$(OBJDIR)/%.o: %.cpp
|
||||
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||
|
||||
clean:
|
||||
$(RM) *.o *.a *.exe
|
||||
|
||||
rebuild: clean all
|
||||
@@ -0,0 +1,82 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#include "map_editor.hpp"
|
||||
|
||||
//-------------------------
|
||||
//Public access members
|
||||
//-------------------------
|
||||
|
||||
MapEditor::MapEditor() {
|
||||
//
|
||||
}
|
||||
|
||||
MapEditor::~MapEditor() {
|
||||
//
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
//Frame loop
|
||||
//-------------------------
|
||||
|
||||
void MapEditor::FrameStart() {
|
||||
//
|
||||
}
|
||||
|
||||
void MapEditor::Update(double delta) {
|
||||
//
|
||||
}
|
||||
|
||||
void MapEditor::FrameEnd() {
|
||||
//
|
||||
}
|
||||
|
||||
void MapEditor::Render(SDL_Surface* const screen) {
|
||||
//
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
//Event handlers
|
||||
//-------------------------
|
||||
|
||||
void MapEditor::MouseMotion(SDL_MouseMotionEvent const& motion) {
|
||||
//
|
||||
}
|
||||
|
||||
void MapEditor::MouseButtonDown(SDL_MouseButtonEvent const& button) {
|
||||
//
|
||||
}
|
||||
|
||||
void MapEditor::MouseButtonUp(SDL_MouseButtonEvent const& button) {
|
||||
//
|
||||
}
|
||||
|
||||
void MapEditor::KeyDown(SDL_KeyboardEvent const& key) {
|
||||
switch(key.keysym.sym) {
|
||||
case SDLK_ESCAPE:
|
||||
QuitEvent();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MapEditor::KeyUp(SDL_KeyboardEvent const& key) {
|
||||
//
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#ifndef MAPEDITOR_HPP_
|
||||
#define MAPEDITOR_HPP_
|
||||
|
||||
#include "base_scene.hpp"
|
||||
|
||||
class MapEditor : public BaseScene {
|
||||
public:
|
||||
//Public access members
|
||||
MapEditor();
|
||||
~MapEditor();
|
||||
|
||||
protected:
|
||||
//Frame loop
|
||||
void FrameStart();
|
||||
void Update(double delta);
|
||||
void FrameEnd();
|
||||
void Render(SDL_Surface* const);
|
||||
|
||||
//Event handlers
|
||||
void MouseMotion(SDL_MouseMotionEvent const&);
|
||||
void MouseButtonDown(SDL_MouseButtonEvent const&);
|
||||
void MouseButtonUp(SDL_MouseButtonEvent const&);
|
||||
void KeyDown(SDL_KeyboardEvent const&);
|
||||
void KeyUp(SDL_KeyboardEvent const&);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#ifndef SCENELIST_HPP_
|
||||
#define SCENELIST_HPP_
|
||||
|
||||
enum class SceneList {
|
||||
//these are reserved
|
||||
QUIT,
|
||||
CONTINUE,
|
||||
FIRST,
|
||||
|
||||
//custom indexes
|
||||
MAPEDITOR,
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -21,6 +21,24 @@
|
||||
*/
|
||||
#include "frame_rate.hpp"
|
||||
|
||||
int FrameRate::frameCount = 0;
|
||||
int FrameRate::lastFrameRate = 0;
|
||||
FrameRate::Clock::time_point FrameRate::tick = FrameRate::Clock::now();
|
||||
#include <chrono>
|
||||
|
||||
typedef std::chrono::high_resolution_clock Clock;
|
||||
|
||||
static int frameCount = 0;
|
||||
static int lastFrameRate = 0;
|
||||
static Clock::time_point tick = Clock::now();
|
||||
|
||||
int ClockFrameRate() {
|
||||
frameCount++;
|
||||
if (Clock::now() - tick >= std::chrono::duration<int>(1)) {
|
||||
lastFrameRate = frameCount;
|
||||
frameCount = 0;
|
||||
tick = Clock::now();
|
||||
}
|
||||
return lastFrameRate;
|
||||
}
|
||||
|
||||
int GetFrameRate() {
|
||||
return lastFrameRate;
|
||||
}
|
||||
|
||||
@@ -22,27 +22,7 @@
|
||||
#ifndef FRAMERATE_HPP_
|
||||
#define FRAMERATE_HPP_
|
||||
|
||||
#include <chrono>
|
||||
|
||||
class FrameRate {
|
||||
public:
|
||||
typedef std::chrono::high_resolution_clock Clock;
|
||||
|
||||
FrameRate() = delete;
|
||||
static int Calculate() {
|
||||
frameCount++;
|
||||
if (Clock::now() - tick >= std::chrono::duration<int>(1)) {
|
||||
lastFrameRate = frameCount;
|
||||
frameCount = 0;
|
||||
tick = Clock::now();
|
||||
}
|
||||
return lastFrameRate;
|
||||
}
|
||||
static int GetFrameRate() { return lastFrameRate; }
|
||||
private:
|
||||
static int frameCount;
|
||||
static int lastFrameRate;
|
||||
static Clock::time_point tick;
|
||||
};
|
||||
int ClockFrameRate();
|
||||
int GetFrameRate();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
|
||||
double operator[](size_t i) {
|
||||
if (i >= 2)
|
||||
throw(std::runtime_error("Out of range"));
|
||||
throw(std::domain_error("Out of range"));
|
||||
return *(&x+i);
|
||||
}
|
||||
|
||||
@@ -53,19 +53,19 @@ public:
|
||||
|
||||
Vector2 operator/(Vector2 v) {
|
||||
if (!v.x || !v.y)
|
||||
throw(std::runtime_error("Divide by zero"));
|
||||
throw(std::domain_error("Divide by zero"));
|
||||
return Vector2(x / v.x, y / v.y);
|
||||
}
|
||||
Vector2 operator/(double d) {
|
||||
if (!d)
|
||||
throw(std::runtime_error("Divide by zero"));
|
||||
throw(std::domain_error("Divide by zero"));
|
||||
return Vector2(x / d, y / d);
|
||||
}
|
||||
|
||||
bool operator==(Vector2 v) { return (x == v.x && y == v.y); }
|
||||
bool operator!=(Vector2 v) { return (x != v.x || y != v.y); }
|
||||
|
||||
//templates
|
||||
//member templates
|
||||
template<typename T> Vector2 operator+=(T t) { return *this = *this + t; }
|
||||
template<typename T> Vector2 operator-=(T t) { return *this = *this - t; }
|
||||
template<typename T> Vector2 operator*=(T t) { return *this = *this * t; }
|
||||
@@ -74,4 +74,13 @@ public:
|
||||
template<typename T> bool operator!=(T t) { return (x != t || y != t); }
|
||||
};
|
||||
|
||||
//non-member templates
|
||||
template<typename T> Vector2 operator+(T t, Vector2 v) { return v + t; }
|
||||
template<typename T> Vector2 operator-(T t, Vector2 v) { return v - t; }
|
||||
template<typename T> Vector2 operator*(T t, Vector2 v) { return v * t; }
|
||||
template<typename T> Vector2 operator/(T t, Vector2 v) { return v / t; }
|
||||
|
||||
template<typename T> bool operator==(T t, Vector2 v) { return v == t; }
|
||||
template<typename T> bool operator!=(T t, Vector2 v) { return v != t; }
|
||||
|
||||
#endif
|
||||
|
||||
@@ -157,9 +157,9 @@ extern DECLSPEC void SDLCALL SDLNet_TCP_Close(TCPsocket sock);
|
||||
/***********************************************************************/
|
||||
|
||||
/* The maximum channels on a a UDP socket */
|
||||
#define SDLNET_MAX_UDPCHANNELS 150
|
||||
#define SDLNET_MAX_UDPCHANNELS 32
|
||||
/* The maximum addresses bound to a single UDP socket channel */
|
||||
#define SDLNET_MAX_UDPADDRESSES 1
|
||||
#define SDLNET_MAX_UDPADDRESSES 4
|
||||
|
||||
typedef struct _UDPsocket *UDPsocket;
|
||||
typedef struct {
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#ifndef CLIENTENTRY_HPP_
|
||||
#define CLIENTENTRY_HPP_
|
||||
|
||||
#include "SDL_net/SDL_net.h"
|
||||
|
||||
struct ClientEntry {
|
||||
int index;
|
||||
IPaddress address;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -20,16 +20,15 @@
|
||||
* distribution.
|
||||
*/
|
||||
#ifndef DEFINES_HPP_
|
||||
#define DEFINES_HPP
|
||||
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#define DEFINES_HPP_
|
||||
|
||||
#define GAME_CHANNEL 0
|
||||
#define CHAT_CHANNEL 1
|
||||
|
||||
typedef std::chrono::high_resolution_clock Clock;
|
||||
#define WALKING_SPEED 140
|
||||
|
||||
std::string itos(int i);
|
||||
enum class CardinalDirection {
|
||||
NORTH, SOUTH, EAST, WEST
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
* distribution.
|
||||
*/
|
||||
#include "network_queue.hpp"
|
||||
#include "service_locator.hpp"
|
||||
#include "singleton.hpp"
|
||||
|
||||
#include "udp_network_utility.hpp"
|
||||
|
||||
@@ -37,7 +37,7 @@ static std::deque<Packet> queue;
|
||||
static bool running = false;
|
||||
|
||||
static int networkQueue(void*) {
|
||||
UDPNetworkUtility* netUtil = ServiceLocator<UDPNetworkUtility>::Get();
|
||||
UDPNetworkUtility* netUtil = Singleton<UDPNetworkUtility>::Get();
|
||||
while(running) {
|
||||
SDL_SemWait(lock);
|
||||
while(netUtil->Receive()) {
|
||||
@@ -102,7 +102,7 @@ Packet popNetworkPacket() {
|
||||
}
|
||||
|
||||
void flushNetworkQueue() {
|
||||
UDPNetworkUtility* netUtil = ServiceLocator<UDPNetworkUtility>::Get();
|
||||
UDPNetworkUtility* netUtil = Singleton<UDPNetworkUtility>::Get();
|
||||
SDL_SemWait(lock);
|
||||
while(netUtil->Receive());
|
||||
queue.clear();
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#ifndef NETWORKQUEUE_HPP_
|
||||
#define NETWORKQUEUE_HPP_
|
||||
|
||||
#include "packet_type.hpp"
|
||||
#include "packet.hpp"
|
||||
|
||||
void beginQueueThread();
|
||||
void endQueueThread();
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#ifndef PACKETTYPE_HPP_
|
||||
#define PACKETTYPE_HPP_
|
||||
|
||||
#include "vector2.hpp"
|
||||
|
||||
#include "SDL_net/SDL_net.h"
|
||||
|
||||
#define PACKET_STRING_SIZE 100
|
||||
|
||||
#pragma pack(push, 0)
|
||||
|
||||
union Packet {
|
||||
//the type of packet being sent
|
||||
enum class Type {
|
||||
NONE = 0,
|
||||
|
||||
PING = 1,
|
||||
PONG = 2,
|
||||
BROADCAST_REQUEST = 3,
|
||||
BROADCAST_RESPONSE = 4,
|
||||
JOIN_REQUEST = 5,
|
||||
JOIN_RESPONSE = 6,
|
||||
DISCONNECT = 7,
|
||||
|
||||
SYNCHRONIZE = 8,
|
||||
|
||||
PLAYER_NEW = 9,
|
||||
PLAYER_DELETE = 10,
|
||||
PLAYER_UPDATE = 11,
|
||||
};
|
||||
|
||||
//metadata on the packet itself
|
||||
struct Metadata {
|
||||
Type type;
|
||||
IPaddress address;
|
||||
int clientIndex;
|
||||
}meta;
|
||||
|
||||
//information about the server
|
||||
struct ServerInformation {
|
||||
Metadata meta;
|
||||
//TODO: version info
|
||||
char name[PACKET_STRING_SIZE];
|
||||
//TODO: player count
|
||||
}serverInfo;
|
||||
|
||||
//information about a specific player
|
||||
struct PlayerInformation {
|
||||
Metadata meta;
|
||||
int index;
|
||||
char handle[PACKET_STRING_SIZE];
|
||||
char avatar[PACKET_STRING_SIZE];
|
||||
Vector2 position;
|
||||
Vector2 motion;
|
||||
//TODO Playerdata
|
||||
}playerInfo;
|
||||
|
||||
//zero the packet
|
||||
Packet() {
|
||||
meta.type = Type::NONE;
|
||||
meta.address.host = 0;
|
||||
meta.address.port = 0;
|
||||
meta.clientIndex = -1;
|
||||
};
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
||||
@@ -1,138 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#ifndef PACKETTYPE_HPP_
|
||||
#define PACKETTYPE_HPP_
|
||||
|
||||
#include "vector2.hpp"
|
||||
|
||||
#include "SDL_net/SDL_net.h"
|
||||
|
||||
#define PACKET_STRING_SIZE 100
|
||||
|
||||
#pragma pack(push, 0)
|
||||
|
||||
enum class PacketType {
|
||||
NONE = 0,
|
||||
|
||||
PING = 1,
|
||||
PONG = 2,
|
||||
BROADCAST_REQUEST = 3,
|
||||
BROADCAST_RESPONSE = 4,
|
||||
JOIN_REQUEST = 5,
|
||||
JOIN_RESPONSE = 6,
|
||||
DISCONNECT = 7,
|
||||
|
||||
SYNCHRONIZE = 8,
|
||||
|
||||
PLAYER_NEW = 9,
|
||||
PLAYER_DELETE = 10,
|
||||
PLAYER_MOVE = 11,
|
||||
};
|
||||
|
||||
struct Metadata {
|
||||
PacketType type;
|
||||
IPaddress address;
|
||||
};
|
||||
|
||||
struct Ping {
|
||||
Metadata meta;
|
||||
};
|
||||
|
||||
struct Pong {
|
||||
Metadata meta;
|
||||
};
|
||||
|
||||
struct BroadcastRequest {
|
||||
Metadata meta;
|
||||
};
|
||||
|
||||
struct BroadcastResponse {
|
||||
Metadata meta;
|
||||
char name[PACKET_STRING_SIZE];
|
||||
//TODO: version
|
||||
};
|
||||
|
||||
struct JoinRequest {
|
||||
Metadata meta;
|
||||
};
|
||||
|
||||
struct JoinResponse {
|
||||
Metadata meta;
|
||||
int clientIndex;
|
||||
//resource list
|
||||
};
|
||||
|
||||
struct Disconnect {
|
||||
Metadata meta;
|
||||
int clientIndex;
|
||||
};
|
||||
|
||||
struct Synchronize {
|
||||
Metadata meta;
|
||||
};
|
||||
|
||||
struct PlayerNew {
|
||||
Metadata meta;
|
||||
int playerIndex;
|
||||
//TODO Playerdata
|
||||
};
|
||||
|
||||
struct PlayerDelete {
|
||||
Metadata meta;
|
||||
int playerIndex;
|
||||
};
|
||||
|
||||
struct PlayerMove {
|
||||
Metadata meta;
|
||||
int playerIndex;
|
||||
Vector2 position;
|
||||
Vector2 motion;
|
||||
};
|
||||
|
||||
union Packet {
|
||||
Packet() {
|
||||
meta.type = PacketType::NONE;
|
||||
meta.address.host = 0;
|
||||
meta.address.port = 0;
|
||||
};
|
||||
Metadata meta;
|
||||
|
||||
Ping ping;
|
||||
Pong pong;
|
||||
BroadcastRequest broadcastRequest;
|
||||
BroadcastResponse broadcastResponse;
|
||||
JoinRequest joinRequest;
|
||||
JoinResponse joinResponse;
|
||||
Disconnect disconnect;
|
||||
|
||||
PlayerNew playerNew;
|
||||
PlayerDelete playerDelete;
|
||||
PlayerMove playerMove;
|
||||
|
||||
#ifdef DEBUG
|
||||
char buffer[1024];
|
||||
#endif
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,38 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#ifndef PLAYERENTRY_HPP_
|
||||
#define PLAYERENTRY_HPP_
|
||||
|
||||
#include "vector2.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
struct PlayerEntry {
|
||||
int index;
|
||||
int clientIndex;
|
||||
std::string handle;
|
||||
std::string avatar;
|
||||
Vector2 position;
|
||||
Vector2 motion;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#ifndef SERVERENTRY_HPP_
|
||||
#define SERVERENTRY_HPP_
|
||||
|
||||
#include "SDL_net/SDL_net.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
struct ServerEntry {
|
||||
std::string name;
|
||||
IPaddress address;
|
||||
//TODO: player count
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -19,24 +19,20 @@
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#ifndef SERVICELOCATOR_HPP_
|
||||
#define SERVICELOCATOR_HPP_
|
||||
#ifndef SINGLETON_HPP_
|
||||
#define SINGLETON_HPP_
|
||||
|
||||
template<typename T>
|
||||
class ServiceLocator {
|
||||
class Singleton {
|
||||
public:
|
||||
static T* Set(T* t) {
|
||||
delete service;
|
||||
return service = t;
|
||||
}
|
||||
static T* Get() {
|
||||
return service;
|
||||
return &instance;
|
||||
}
|
||||
private:
|
||||
static T* service;
|
||||
static T instance;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
T* ServiceLocator<T>::service = nullptr;
|
||||
T Singleton<T>::instance;
|
||||
|
||||
#endif
|
||||
@@ -19,7 +19,7 @@
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#include "defines.hpp"
|
||||
#include "utilities.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#ifndef UTILITIES_HPP_
|
||||
#define UTILITIES_HPP_
|
||||
|
||||
#include <string>
|
||||
|
||||
std::string itos(int i);
|
||||
|
||||
#endif
|
||||
@@ -1,7 +1,6 @@
|
||||
OUTDIR=out
|
||||
|
||||
all: $(OUTDIR)
|
||||
$(MAKE) -C SDL_net
|
||||
$(MAKE) -C codebase
|
||||
$(MAKE) -C common
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ all: $(OUTDIR)
|
||||
$(MAKE) -C libs
|
||||
$(MAKE) -C server
|
||||
$(MAKE) -C client
|
||||
$(MAKE) -C editor
|
||||
$(MAKE) -C test
|
||||
|
||||
$(OUTDIR):
|
||||
|
||||
+1
-1
@@ -16,5 +16,5 @@ interface = rsc/graphics/interface
|
||||
|
||||
#debugging
|
||||
debug = true
|
||||
avatar = elliot2.bmp
|
||||
avatar = elliot
|
||||
handle = UserName
|
||||
|
||||
+145
-65
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -44,14 +45,13 @@ ServerApplication::~ServerApplication() {
|
||||
* operations.
|
||||
* Important things to note:
|
||||
* The APIs are initiated here.
|
||||
* The global objects are created here.
|
||||
* The global objects are initialized here.
|
||||
* The ConfigUtility's call to Load() also ensures that the "rsc\" folder is in the directory. It's easy to forget it.
|
||||
*/
|
||||
|
||||
void ServerApplication::Init() {
|
||||
//load the config file
|
||||
try {
|
||||
configUtil = ServiceLocator<ConfigUtility>::Set(new ConfigUtility());
|
||||
configUtil->Load("rsc/config.cfg");
|
||||
}
|
||||
catch(std::runtime_error& e) {
|
||||
@@ -70,10 +70,7 @@ void ServerApplication::Init() {
|
||||
throw(runtime_error("Failed to initialize SDL_net"));
|
||||
}
|
||||
|
||||
//instanciate the remaining services
|
||||
netUtil = ServiceLocator<UDPNetworkUtility>::Set(new UDPNetworkUtility());
|
||||
|
||||
//initiate the remaining services
|
||||
//initiate the remaining singletons
|
||||
netUtil->Open(configUtil->Int("server.port"), sizeof(Packet));
|
||||
|
||||
//create the threads
|
||||
@@ -88,17 +85,30 @@ void ServerApplication::Init() {
|
||||
}
|
||||
|
||||
void ServerApplication::Proc() {
|
||||
Clock::duration delta = Clock::now() - lastTick;
|
||||
lastTick = Clock::now();
|
||||
typedef chrono::high_resolution_clock Clock;
|
||||
|
||||
Clock::time_point lastTick = Clock::now();
|
||||
Clock::duration delta;
|
||||
|
||||
while(running) {
|
||||
try {
|
||||
//process all packets on the network queue
|
||||
while(HandlePacket(popNetworkPacket()));
|
||||
}
|
||||
catch(exception& e) {
|
||||
//handle any errors
|
||||
cerr << "Network Error: " << e.what() << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
//get the time since last update
|
||||
delta = Clock::now() - lastTick;
|
||||
lastTick = Clock::now();
|
||||
|
||||
//update the world
|
||||
UpdateWorld(double(delta.count()) / Clock::duration::period::den);
|
||||
|
||||
//give the machine a break
|
||||
SDL_Delay(10);
|
||||
}
|
||||
}
|
||||
@@ -107,13 +117,9 @@ void ServerApplication::Quit() {
|
||||
//close the threads
|
||||
endQueueThread();
|
||||
|
||||
//clean up the services
|
||||
//clean up the singletons
|
||||
netUtil->Close();
|
||||
|
||||
//delete the services
|
||||
configUtil = ServiceLocator<ConfigUtility>::Set(nullptr);
|
||||
netUtil = ServiceLocator<UDPNetworkUtility>::Set(nullptr);
|
||||
|
||||
//deinitialize the APIs
|
||||
SDLNet_Quit();
|
||||
}
|
||||
@@ -123,8 +129,15 @@ void ServerApplication::Quit() {
|
||||
//-------------------------
|
||||
|
||||
void ServerApplication::UpdateWorld(double delta) {
|
||||
for (auto it : players) {
|
||||
it.second.Update(delta);
|
||||
//the recalc here each loop is a stopgap, see issue #9 for details
|
||||
for (auto& it : players) {
|
||||
if (it.second.motion.x != 0 && it.second.motion.y != 0) {
|
||||
constexpr double d = 1.0/sqrt(2);
|
||||
it.second.position += it.second.motion * delta * d;
|
||||
}
|
||||
else {
|
||||
it.second.position += it.second.motion * delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,95 +147,162 @@ void ServerApplication::UpdateWorld(double delta) {
|
||||
|
||||
int ServerApplication::HandlePacket(Packet p) {
|
||||
switch(p.meta.type) {
|
||||
case PacketType::NONE:
|
||||
case Packet::Type::NONE:
|
||||
//DO NOTHING
|
||||
return 0;
|
||||
break;
|
||||
case PacketType::PING:
|
||||
case Packet::Type::PING:
|
||||
//quick pong
|
||||
p.meta.type = PacketType::PONG;
|
||||
p.meta.type = Packet::Type::PONG;
|
||||
netUtil->Send(&p.meta.address, &p, sizeof(Packet));
|
||||
break;
|
||||
case PacketType::PONG:
|
||||
case Packet::Type::PONG:
|
||||
//
|
||||
break;
|
||||
case PacketType::BROADCAST_REQUEST:
|
||||
HandleBroadcast(p.broadcastRequest);
|
||||
case Packet::Type::BROADCAST_REQUEST:
|
||||
HandleBroadcast(p);
|
||||
break;
|
||||
// case PacketType::BROADCAST_RESPONSE:
|
||||
// //
|
||||
// break;
|
||||
case PacketType::JOIN_REQUEST:
|
||||
HandleConnection(p.joinRequest);
|
||||
case Packet::Type::JOIN_REQUEST:
|
||||
HandleConnection(p);
|
||||
break;
|
||||
// case PacketType::JOIN_RESPONSE:
|
||||
// //
|
||||
// break;
|
||||
case PacketType::DISCONNECT:
|
||||
HandleDisconnection(p.disconnect);
|
||||
case Packet::Type::DISCONNECT:
|
||||
HandleDisconnection(p);
|
||||
break;
|
||||
case Packet::Type::SYNCHRONIZE:
|
||||
SynchronizeEverything(p);
|
||||
break;
|
||||
case Packet::Type::PLAYER_NEW:
|
||||
AddPlayer(p);
|
||||
RelayPacket(p);
|
||||
break;
|
||||
case Packet::Type::PLAYER_DELETE:
|
||||
RemovePlayer(p);
|
||||
RelayPacket(p);
|
||||
break;
|
||||
case Packet::Type::PLAYER_UPDATE:
|
||||
UpdatePlayer(p);
|
||||
RelayPacket(p);
|
||||
break;
|
||||
// case PacketType::SYNCHRONIZE:
|
||||
// //
|
||||
// break;
|
||||
// case PacketType::PLAYER_NEW:
|
||||
// //
|
||||
// break;
|
||||
// case PacketType::PLAYER_DELETE:
|
||||
// //
|
||||
// break;
|
||||
// case PacketType::PLAYER_MOVE:
|
||||
// //
|
||||
// break;
|
||||
default:
|
||||
throw(runtime_error("Failed to recognize the packet type: " + itos(int(p.meta.type))));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ServerApplication::HandleBroadcast(BroadcastRequest& bcast) {
|
||||
void ServerApplication::RelayPacket(Packet& p) {
|
||||
//pump this packet to all clients
|
||||
for (auto& it : clients) {
|
||||
netUtil->Send(&it.second.address, &p, sizeof(Packet));
|
||||
}
|
||||
}
|
||||
|
||||
void ServerApplication::SynchronizeEverything(Packet& sync) {
|
||||
//send all known data to this client
|
||||
//TODO multithreading?
|
||||
|
||||
//all players
|
||||
Packet p;
|
||||
p.meta.type = Packet::Type::PLAYER_UPDATE;
|
||||
for (auto& it : players) {
|
||||
p.meta.clientIndex = it.second.clientIndex;
|
||||
|
||||
p.playerInfo.index = it.second.index;
|
||||
snprintf(p.playerInfo.handle, PACKET_STRING_SIZE, "%s", it.second.handle.c_str());
|
||||
snprintf(p.playerInfo.avatar, PACKET_STRING_SIZE, "%s", it.second.avatar.c_str());
|
||||
p.playerInfo.position = it.second.position;
|
||||
p.playerInfo.motion = it.second.motion;
|
||||
|
||||
netUtil->Send(&clients[sync.meta.clientIndex].address, &p, sizeof(Packet));
|
||||
}
|
||||
}
|
||||
|
||||
void ServerApplication::HandleBroadcast(Packet& bcast) {
|
||||
//respond to a broadcast request with the server's data
|
||||
Packet p;
|
||||
p.meta.type = PacketType::BROADCAST_RESPONSE;
|
||||
snprintf(p.broadcastResponse.name, PACKET_STRING_SIZE, "%s", configUtil->CString("server.name"));
|
||||
p.meta.type = Packet::Type::BROADCAST_RESPONSE;
|
||||
snprintf(p.serverInfo.name, PACKET_STRING_SIZE, "%s", configUtil->CString("server.name"));
|
||||
//TODO version information
|
||||
netUtil->Send(&bcast.meta.address, &p, sizeof(Packet));
|
||||
}
|
||||
|
||||
void ServerApplication::HandleConnection(JoinRequest& request) {
|
||||
if (clients.size() >= SDLNET_MAX_UDPCHANNELS) {
|
||||
//ignore the new connection if there's too many clients connected
|
||||
return;
|
||||
}
|
||||
//create the containers
|
||||
ClientData client = { uniqueIndex++ };
|
||||
|
||||
//bind the address
|
||||
client.channel = netUtil->Bind(&request.meta.address);
|
||||
void ServerApplication::HandleConnection(Packet& request) {
|
||||
//create the entries
|
||||
ClientEntry newClient = {
|
||||
uniqueIndex++,
|
||||
request.meta.address
|
||||
};
|
||||
|
||||
//push this information
|
||||
clients[client.index] = client;
|
||||
clients[newClient.index] = newClient;
|
||||
|
||||
//send the player their information
|
||||
Packet p;
|
||||
p.meta.type = PacketType::JOIN_RESPONSE;
|
||||
p.joinResponse.clientIndex = client.index;
|
||||
//TODO: resource list
|
||||
netUtil->Send(client.channel, &p, sizeof(Packet));
|
||||
p.meta.type = Packet::Type::JOIN_RESPONSE;
|
||||
p.meta.clientIndex = newClient.index;
|
||||
|
||||
//pretty
|
||||
cout << "New connection: index " << client.index << endl;
|
||||
//TODO: resource list
|
||||
|
||||
netUtil->Send(&newClient.address, &p, sizeof(Packet));
|
||||
|
||||
//debugging
|
||||
cout << "New connection: index " << newClient.index << endl;
|
||||
cout << "number of clients: " << clients.size() << endl;
|
||||
}
|
||||
|
||||
void ServerApplication::HandleDisconnection(Disconnect& disconnect) {
|
||||
void ServerApplication::HandleDisconnection(Packet& disconnect) {
|
||||
//disconnect a client (redundant message)
|
||||
netUtil->Send(clients[disconnect.clientIndex].channel, &disconnect, sizeof(Packet));
|
||||
netUtil->Unbind(clients[disconnect.clientIndex].channel);
|
||||
clients.erase(disconnect.clientIndex);
|
||||
netUtil->Send(&clients[disconnect.meta.clientIndex].address, &disconnect, sizeof(Packet));
|
||||
clients.erase(disconnect.meta.clientIndex);
|
||||
|
||||
//remove the player...
|
||||
//TODO remove the player...
|
||||
//remove if(...)
|
||||
|
||||
//pretty
|
||||
cout << "Lost connection: index " << disconnect.clientIndex << endl;
|
||||
//remove the player from other clients
|
||||
|
||||
//debugging
|
||||
cout << "Lost connection: index " << disconnect.meta.clientIndex << endl;
|
||||
cout << "number of clients: " << clients.size() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void ServerApplication::AddPlayer(Packet& p) {
|
||||
//add the player
|
||||
PlayerEntry newPlayer = {
|
||||
uniqueIndex++,
|
||||
p.meta.clientIndex,
|
||||
p.playerInfo.handle,
|
||||
p.playerInfo.avatar,
|
||||
p.playerInfo.position,
|
||||
p.playerInfo.motion
|
||||
};
|
||||
|
||||
players[newPlayer.index] = newPlayer;
|
||||
|
||||
//prep for relay
|
||||
p.playerInfo.index = newPlayer.index;
|
||||
|
||||
//debugging
|
||||
cout << "New player " << newPlayer.handle << " has joined the game" << endl;
|
||||
cout << "Number of players: " << players.size() << endl;
|
||||
}
|
||||
|
||||
void ServerApplication::RemovePlayer(Packet& p) {
|
||||
if (players.find(p.playerInfo.index) == players.end()) {
|
||||
throw(runtime_error("Player to delete not found"));
|
||||
}
|
||||
|
||||
players.erase(p.playerInfo.index);
|
||||
}
|
||||
|
||||
void ServerApplication::UpdatePlayer(Packet& p) {
|
||||
if (players.find(p.playerInfo.index) == players.end()) {
|
||||
throw(runtime_error("Player to update not found"));
|
||||
}
|
||||
players[p.playerInfo.index].position = p.playerInfo.position;
|
||||
players[p.playerInfo.index].motion = p.playerInfo.motion;
|
||||
}
|
||||
|
||||
@@ -22,11 +22,14 @@
|
||||
#ifndef SERVERAPPLICATION_HPP_
|
||||
#define SERVERAPPLICATION_HPP_
|
||||
|
||||
#include "defines.hpp"
|
||||
#include "packet_type.hpp"
|
||||
#include "service_locator.hpp"
|
||||
#include "utilities.hpp"
|
||||
#include "packet.hpp"
|
||||
#include "singleton.hpp"
|
||||
#include "network_queue.hpp"
|
||||
|
||||
#include "client_entry.hpp"
|
||||
#include "player_entry.hpp"
|
||||
|
||||
#include "config_Utility.hpp"
|
||||
#include "udp_network_utility.hpp"
|
||||
#include "vector2.hpp"
|
||||
@@ -34,27 +37,8 @@
|
||||
#include "SDL/SDL_thread.h"
|
||||
|
||||
#include <map>
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
|
||||
struct ClientData {
|
||||
int index;
|
||||
int channel;
|
||||
int playerIndex;
|
||||
};
|
||||
|
||||
struct PlayerData {
|
||||
int index;
|
||||
int clientIndex;
|
||||
std::string handle;
|
||||
std::string avatar;
|
||||
Vector2 position;
|
||||
Vector2 motion;
|
||||
|
||||
void Update(double delta) {
|
||||
position += motion * delta;
|
||||
}
|
||||
};
|
||||
#include <algorithm>
|
||||
|
||||
class ServerApplication {
|
||||
public:
|
||||
@@ -65,25 +49,32 @@ public:
|
||||
void Quit();
|
||||
|
||||
ServerApplication(ServerApplication const&) = delete;
|
||||
ServerApplication(ServerApplication const&&) = delete;
|
||||
private:
|
||||
//game loop
|
||||
void UpdateWorld(double delta);
|
||||
|
||||
//network loop
|
||||
int HandlePacket(Packet p);
|
||||
void HandleBroadcast(BroadcastRequest&);
|
||||
void HandleConnection(JoinRequest&);
|
||||
void HandleDisconnection(Disconnect&);
|
||||
int HandlePacket(Packet);
|
||||
void RelayPacket(Packet&);
|
||||
|
||||
void SynchronizeEverything(Packet&);
|
||||
|
||||
void HandleBroadcast(Packet&);
|
||||
void HandleConnection(Packet&);
|
||||
void HandleDisconnection(Packet&);
|
||||
|
||||
void AddPlayer(Packet&);
|
||||
void RemovePlayer(Packet&);
|
||||
void UpdatePlayer(Packet&);
|
||||
|
||||
//services
|
||||
ConfigUtility* configUtil = nullptr;
|
||||
UDPNetworkUtility* netUtil = nullptr;
|
||||
ConfigUtility* configUtil = Singleton<ConfigUtility>::Get();
|
||||
UDPNetworkUtility* netUtil = Singleton<UDPNetworkUtility>::Get();
|
||||
|
||||
//members
|
||||
Clock::time_point lastTick = Clock::now();
|
||||
|
||||
std::map<int, ClientData> clients;
|
||||
std::map<int, PlayerData> players;
|
||||
std::map<int, ClientEntry> clients;
|
||||
std::map<int, PlayerEntry> players;
|
||||
|
||||
bool running = false;
|
||||
|
||||
|
||||
+1
-5
@@ -1,5 +1 @@
|
||||
#include "service_locator.hpp"
|
||||
|
||||
int FooBar() {
|
||||
return *ServiceLocator<int>::Get();
|
||||
}
|
||||
#include "foobar.hpp"
|
||||
|
||||
+5
-2
@@ -1,7 +1,10 @@
|
||||
#include "defines.hpp"
|
||||
#include "packet.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(int, char**) {
|
||||
std::string s = itos(5);
|
||||
Packet p;
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user