Compare commits

..

58 Commits

Author SHA1 Message Date
Kayne Ruse c60709d047 Tested SendAll(), end of this prototype 2013-06-07 03:22:29 +10:00
Kayne Ruse 6b677e5de8 I'm just going to ditch this prototype soon 2013-06-07 03:14:23 +10:00
Kayne Ruse d347545c20 Moved documentation into doc branch 2013-06-06 02:55:06 +10:00
Kayne Ruse dfac9c1518 Reviewing the progress so far 2013-06-05 03:50:46 +10:00
Kayne Ruse 0cfb47e641 Fixed FPS counter 2013-06-04 21:28:00 +10:00
Kayne Ruse a260f29d4f Imported update to FrameRate 2013-06-04 21:11:21 +10:00
Kayne Ruse a8b798ddff Players are moving and animating correctly 2013-06-04 20:39:44 +10:00
Kayne Ruse 231db701e4 Spliced in updates to the scene system; program compiles & runs, player's don't move 2013-06-04 20:20:56 +10:00
Kayne Ruse 783e8928d6 Imported graphics updates from Codebase 2013-06-04 05:05:40 +10:00
Kayne Ruse 6a16e341ec Trying to create a fixed time slice system 2013-06-02 04:00:26 +10:00
Kayne Ruse 4c670c3a22 Fixed non-debug builds not compiling 2013-05-26 03:02:44 +10:00
Kayne Ruse 488283be50 Added copyright info 2013-05-25 20:45:53 +10:00
Kayne Ruse 4c228e0e36 Started working on receiving information about other players 2013-05-24 19:21:50 +10:00
Kayne Ruse 0d3a69106f Moved some code 2013-05-24 18:06:29 +10:00
Kayne Ruse e2fed23659 Minor tweaks 2013-05-24 17:15:58 +10:00
Kayne Ruse 1ab963099d Connections and disconnections between client and server are functioning 2013-05-24 15:39:42 +10:00
Kayne Ruse 0b2af1d80f Smoothed naming and other conventions 2013-05-24 00:51:04 +10:00
Kayne Ruse cce1a874bf Join request is sent, but I need to plan the next section out in detail 2013-05-22 17:31:13 +10:00
Kayne Ruse 66f54dca0b Fixed magic number issues 2013-05-21 01:45:36 +10:00
Kayne Ruse bf73b542f1 Implemented server selection interface 2013-05-20 18:54:10 +10:00
Kayne Ruse d76cbe13da Added basic server list, and added yield calls 2013-05-20 17:43:16 +10:00
Kayne Ruse d5409d2006 Drafted a basic networking protocol, and hooked a button up to the network broadcast 2013-05-20 04:49:06 +10:00
Kayne Ruse 7866f46ed5 packet is being sent and received, bare-bones ping-pong is working 2013-05-20 01:02:15 +10:00
Kayne Ruse b587759203 Adjusted Vector2 2013-05-19 22:02:55 +10:00
Kayne Ruse f8c174741d Wrapper completed & tested; adjusted many systems 2013-05-19 21:27:24 +10:00
Kayne Ruse 000e3707ed Moved common files (such as Codebase files) into their own directory 2013-05-19 05:50:31 +10:00
Kayne Ruse b3691a341c Started working on a simple UDP wrapper 2013-05-19 04:25:35 +10:00
Kayne Ruse d2087be9ac Resurrected SDL_net 2013-05-17 21:05:50 +10:00
Kayne Ruse 5ade2cc98e Ripped out all networking systems; simply not working correctly 2013-05-17 19:59:31 +10:00
Kayne Ruse 24e48dec53 very buggy system working, but only works properly with one client at a time due to recv blocking 2013-05-17 19:32:45 +10:00
Kayne Ruse 738320e88e Switched TestSystems and InGame 2013-05-16 19:14:38 +10:00
Kayne Ruse f04c7fa161 Removed singletons 2013-05-16 17:02:21 +10:00
Kayne Ruse 30d163ec80 Implemented main menu and buttons 2013-05-15 23:20:47 +10:00
Kayne Ruse 613d9cec08 Imported updates from Codebase 2013-05-15 19:49:27 +10:00
Kayne Ruse 9f76b19a3c Changed the first scene after the splash screen 2013-05-13 00:15:11 +10:00
Kayne Ruse cc00129542 Implemented the splash screen and config file 2013-05-12 02:33:08 +10:00
Kayne Ruse 6a19d0a312 Created the basic program flow 2013-05-11 23:51:02 +10:00
Kayne Ruse 4671afe900 Basic connection between server and unit 2013-05-10 19:57:53 +10:00
Kayne Ruse a667fae21a Updated this project to the new standard, see details.
After a significant modification to the Codebase library, I imported a lot
of the Codebase updates back to this porject. Some files that exist in
Codebase still carry the zlib license header; these files are still under
the zlib license.

Following a significant struggle with SDL_net, I've decided to ditch that
library and write my own version. It currently only supports TCP
networking, and only works on windows platforms,  but it is sufficient at
this time.
2013-05-10 17:04:46 +10:00
Kayne Ruse f0d4ef0675 Changed my mind about networking system structure 2013-05-04 14:00:30 +10:00
Kayne Ruse 2dedfa9505 So that's what I was doing wrong 2013-05-04 03:20:02 +10:00
Kayne Ruse f0e7550b7d What am I doing wrong? 2013-05-04 01:48:31 +10:00
Kayne Ruse 96f0821d9b Imported ConfigUtility, updating it for this project 2013-05-03 02:22:34 +10:00
Kayne Ruse f349e59fd3 Worked out the basic server layout 2013-05-03 00:55:47 +10:00
Kayne Ruse b935fcf1d1 Created empty TCPNetworkManager; needs work, I don't even like the name 2013-05-02 22:46:11 +10:00
Kayne Ruse 95f2d212ef Created PlayerManager 2013-05-02 22:45:30 +10:00
Kayne Ruse 80004ca8d4 merging various commits and stashes 2013-05-02 22:45:26 +10:00
Kayne Ruse fe04561b26 Updated the README, and added a reference to the wiki 2013-05-02 21:08:28 +10:00
Kayne Ruse 63aa248056 Changed *.h files to *.hpp 2013-05-02 20:28:12 +10:00
Kayne Ruse cf82679109 modified makefile to create directories 2013-05-01 20:58:10 +10:00
Kayne Ruse ecdf658463 Moved working systems into InGame 2013-04-29 17:25:56 +10:00
Kayne Ruse c9447fcf3b Fixed diagonal player movement 2013-04-29 15:55:21 +10:00
Kayne Ruse 7dafb372b1 Created Player; not happy with movement 2013-04-29 08:27:03 +10:00
Kayne Ruse 392ef1ef32 Created SpriteSheet 2013-04-29 04:18:20 +10:00
Kayne Ruse d72a3f4fb5 Created Image 2013-04-29 02:50:58 +10:00
Kayne Ruse 1226fa08ca Created SurfaceManager 2013-04-28 23:04:17 +10:00
Kayne Ruse 79304f24b8 Imported basics
project directory
client - scene system
server - empty main
SDL_net source
graphical resources
2013-04-28 04:37:14 +10:00
Kayne Ruse 31d5b3f618 Initial commit 2013-04-26 03:03:14 +10:00
77 changed files with 1398 additions and 1954 deletions
-3
View File
@@ -12,9 +12,6 @@ Out/
#Project generated files
*.db
*.o
*.a
*.exe
#Shell files
*.bat
+3 -4
View File
@@ -1,16 +1,15 @@
_This project is currently in it's early prototype stage. You can see other versions in various branches, 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.
## 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.
* [Codebase](https://github.com/Ratstail91/Codebase) - generic reusable code modules
* [SDL_net](http://www.libsdl.org/projects/SDL_net/) - SDL's networking extension; modified source included under libs/SDL_net
* [Codebase](https://github.com/Ratstail91/Codebase) - files included locally; modifications will be included upstream further into this project.
## 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.
* You need to build the library in the common/ directroy before any others.
* 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).
+69
View File
@@ -0,0 +1,69 @@
#include "combat.hpp"
#include <iostream>
using namespace std;
//-------------------------
//Public access members
//-------------------------
Combat::Combat() {
#ifdef DEBUG
cout << "entering Combat" << endl;
#endif
}
Combat::~Combat() {
#ifdef DEBUG
cout << "leaving Combat" << endl;
#endif
}
//-------------------------
//Frame loop
//-------------------------
void Combat::FrameStart() {
//
}
void Combat::Update(double delta) {
//
}
void Combat::FrameEnd() {
//
}
void Combat::Render(SDL_Surface* const screen) {
//
}
//-------------------------
//Event handlers
//-------------------------
void Combat::MouseMotion(SDL_MouseMotionEvent const& motion) {
//
}
void Combat::MouseButtonDown(SDL_MouseButtonEvent const& button) {
//
}
void Combat::MouseButtonUp(SDL_MouseButtonEvent const& button) {
//
}
void Combat::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE:
QuitEvent();
break;
}
}
void Combat::KeyUp(SDL_KeyboardEvent const& key) {
//
}
+27
View File
@@ -0,0 +1,27 @@
#ifndef COMBAT_HPP_
#define COMBAT_HPP_
#include "base_scene.hpp"
class Combat : public BaseScene {
public:
/* Public access members */
Combat();
~Combat();
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
+9
View File
@@ -0,0 +1,9 @@
#ifndef DEFINES_HPP_
#define DEFINES_HPP_
enum class Direction {
NORTH = 1, SOUTH = 2,
EAST = 3, WEST = 4
};
#endif
-90
View File
@@ -1,90 +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.
*/
#include "in_combat.hpp"
#include <iostream>
using namespace std;
//-------------------------
//Public access members
//-------------------------
InCombat::InCombat() {
#ifdef DEBUG
cout << "entering InCombat" << endl;
#endif
}
InCombat::~InCombat() {
#ifdef DEBUG
cout << "leaving InCombat" << endl;
#endif
}
//-------------------------
//Frame loop
//-------------------------
void InCombat::FrameStart() {
//
}
void InCombat::Update(double delta) {
//
}
void InCombat::FrameEnd() {
//
}
void InCombat::Render(SDL_Surface* const screen) {
//
}
//-------------------------
//Event handlers
//-------------------------
void InCombat::MouseMotion(SDL_MouseMotionEvent const& motion) {
//
}
void InCombat::MouseButtonDown(SDL_MouseButtonEvent const& button) {
//
}
void InCombat::MouseButtonUp(SDL_MouseButtonEvent const& button) {
//
}
void InCombat::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE:
QuitEvent();
break;
}
}
void InCombat::KeyUp(SDL_KeyboardEvent const& key) {
//
}
-48
View File
@@ -1,48 +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 INCOMBAT_HPP_
#define INCOMBAT_HPP_
#include "base_scene.hpp"
class InCombat : public BaseScene {
public:
/* Public access members */
InCombat();
~InCombat();
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
+120
View File
@@ -0,0 +1,120 @@
#include "in_game.hpp"
#include <iostream>
using namespace std;
//-------------------------
//Public access members
//-------------------------
InGame::InGame(ConfigUtility* cUtil, SurfaceManager* sMgr, UDPNetworkUtility* nUtil, int* ID) {
#ifdef DEBUG
cout << "entering InGame" << endl;
#endif
configUtil = cUtil;
surfaceMgr = sMgr;
netUtil = nUtil;
playerID = ID;
cout << "playerID: " << *playerID << endl;
}
InGame::~InGame() {
//placeholder disconnect
PacketData p;
p.type = PacketList::DISCONNECT;
p.disconnect.playerID = *playerID;
*playerID = -1;
netUtil->Send(0, &p, sizeof(PacketData));
netUtil->Unbind(0);
#ifdef DEBUG
cout << "leaving InGame" << endl;
#endif
}
//-------------------------
//Frame loop
//-------------------------
void InGame::FrameStart() {
//
}
void InGame::Update(double delta) {
Receive();
}
void InGame::Receive() {
PacketData packet;
while(netUtil->Receive()) {
memcpy(&packet, netUtil->GetInData(), sizeof(PacketData));
switch(packet.type) {
// case PacketList::NONE:
// //
// break;
// case PacketList::PING:
// //
// break;
// case PacketList::PONG:
// //
// break;
// case PacketList::JOINREQUEST:
// //
// break;
// case PacketList::JOINCONFIRM:
// //
// break;
// case PacketList::DISCONNECT:
// //
// break;
// case PacketList::SYNCHRONIZE:
// //
// break;
case PacketList::NEWPLAYER:
cout << "NEWPLAYER triggered" << endl;
break;
case PacketList::DELETEPLAYER:
cout << "DELETEPLAYER triggered" << endl;
break;
// case PacketList::MOVEMENT:
// //
// break;
}
}
}
void InGame::FrameEnd() {
//
}
void InGame::Render(SDL_Surface* const screen) {
//
}
//-------------------------
//Event handlers
//-------------------------
void InGame::MouseMotion(SDL_MouseMotionEvent const& motion) {
//
}
void InGame::MouseButtonDown(SDL_MouseButtonEvent const& button) {
//
}
void InGame::MouseButtonUp(SDL_MouseButtonEvent const& button) {
//
}
void InGame::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE:
QuitEvent();
break;
}
}
void InGame::KeyUp(SDL_KeyboardEvent const& key) {
//
}
+39
View File
@@ -0,0 +1,39 @@
#ifndef INGAME_HPP_
#define INGAME_HPP_
#include "base_scene.hpp"
#include "config_utility.hpp"
#include "surface_manager.hpp"
#include "udp_network_utility.hpp"
#include "packet_list.hpp"
class InGame : public BaseScene {
public:
//Public access members
InGame(ConfigUtility*, SurfaceManager*, UDPNetworkUtility*, int* playerID);
~InGame();
protected:
//Frame loop
void FrameStart();
void Update(double delta);
void Receive();
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&);
//members
ConfigUtility* configUtil = nullptr;
SurfaceManager* surfaceMgr = nullptr;
UDPNetworkUtility* netUtil = nullptr;
int* playerID = nullptr;
};
#endif
-173
View File
@@ -1,173 +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.
*/
#include "in_world.hpp"
#include <iostream>
using namespace std;
//-------------------------
//Public access members
//-------------------------
InWorld::InWorld() {
#ifdef DEBUG
cout << "entering InWorld" << endl;
#endif
cout << "Client Index: " << infoMgr->GetClientIndex() << endl;
}
InWorld::~InWorld() {
#ifdef DEBUG
cout << "leaving InWorld" << endl;
#endif
}
//-------------------------
//Frame loop
//-------------------------
void InWorld::FrameStart() {
//
}
void InWorld::Update(double delta) {
while(HandlePacket(popNetworkPacket()));
}
void InWorld::FrameEnd() {
//
}
void InWorld::Render(SDL_Surface* const screen) {
//
}
//-------------------------
//Event handlers
//-------------------------
void InWorld::QuitEvent() {
//ensure that the client is disconnected properly
ExitGame();
SetNextScene(SceneList::QUIT);
}
void InWorld::MouseMotion(SDL_MouseMotionEvent const& motion) {
//
}
void InWorld::MouseButtonDown(SDL_MouseButtonEvent const& button) {
//
}
void InWorld::MouseButtonUp(SDL_MouseButtonEvent const& button) {
//
}
void InWorld::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE:
ExitGame();
break;
}
}
void InWorld::KeyUp(SDL_KeyboardEvent const& key) {
//
}
//-------------------------
//Utilities
//-------------------------
int InWorld::HandlePacket(Packet p) {
switch(p.meta.type) {
case PacketType::NONE:
//DO NOTHING
return 0;
break;
case PacketType::PING:
//quick pong
p.meta.type = PacketType::PONG;
netUtil->Send(&p.meta.address, &p, sizeof(Packet));
break;
case PacketType::PONG:
//
break;
// case PacketType::BROADCAST_REQUEST:
// //
// break;
// case PacketType::BROADCAST_RESPONSE:
// //
// break;
// case PacketType::JOIN_REQUEST:
// //
// break;
// case PacketType::JOIN_RESPONSE:
// //
// break;
case PacketType::DISCONNECT:
HandleDisconnection(p.disconnect);
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 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));
netUtil->Unbind(GAME_CHANNEL);
endQueueThread();
//reset the client
infoMgr->ResetClientIndex();
}
void InWorld::ExitGame() {
Disconnect();
SetNextScene(SceneList::MAINMENU);
cout << "The game session has ended" << endl;
}
void InWorld::HandleDisconnection(::Disconnect& disconnect) {
Disconnect();
SetNextScene(SceneList::MAINMENU);
cout << "You have been disconnected" << endl;
}
-75
View File
@@ -1,75 +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 INWORLD_HPP_
#define INWORLD_HPP_
#include "base_scene.hpp"
#include "defines.hpp"
#include "service_locator.hpp"
#include "packet_type.hpp"
#include "network_queue.hpp"
#include "information_manager.hpp"
#include "config_utility.hpp"
#include "surface_manager.hpp"
#include "udp_network_utility.hpp"
#include "button.hpp"
#include "raster_font.hpp"
class InWorld : public BaseScene {
public:
//Public access members
InWorld();
~InWorld();
protected:
//Frame loop
void FrameStart();
void Update(double delta);
void FrameEnd();
void Render(SDL_Surface* const);
//Event handlers
void QuitEvent();
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&);
//Utilities
int HandlePacket(Packet p);
void Disconnect();
void ExitGame();
void HandleDisconnection(::Disconnect&);
//services
ConfigUtility* configUtil = ServiceLocator<ConfigUtility>::Get();
SurfaceManager* surfaceMgr = ServiceLocator<SurfaceManager>::Get();
UDPNetworkUtility* netUtil = ServiceLocator<UDPNetworkUtility>::Get();
InformationManager* infoMgr = ServiceLocator<InformationManager>::Get();
//members
//...
};
#endif
-34
View File
@@ -1,34 +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 INFORMATIONMANAGER_HPP_
#define INFORMATIONMANAGER_HPP_
class InformationManager {
public:
int SetClientIndex(int i) { return clientIndex = i; }
int GetClientIndex() { return clientIndex; }
void ResetClientIndex() { clientIndex = -1; }
private:
int clientIndex = -1;
};
#endif
+120 -144
View File
@@ -1,26 +1,6 @@
/* 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 "lobby.hpp"
#include <exception>
#include <iostream>
using namespace std;
@@ -29,30 +9,38 @@ using namespace std;
//Public access members
//-------------------------
Lobby::Lobby() {
Lobby::Lobby(ConfigUtility* cUtil, SurfaceManager* sMgr, UDPNetworkUtility* nUtil, int* ID) {
#ifdef DEBUG
cout << "entering Lobby" << endl;
#endif
refreshButton.Setup(50, 50, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Refresh");
joinButton.Setup(50, 100, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Join");
backButton.Setup(50, 150, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Back");
//globals
configUtil = cUtil;
surfaceMgr = sMgr;
netUtil = nUtil;
playerID = ID;
//members
font.SetSurface(surfaceMgr->Get("font"));
listBox.x = 280;
//the buttons
buttonMap["ping"] = new Button(50, 50 , surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Refresh");
buttonMap["join"] = new Button(50, 100, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Join");
buttonMap["back"] = new Button(50, 150, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Back");
//drawing information for the server list
listBox.x = 250;
listBox.y = 50;
listBox.w = GetScreen()->w - listBox.x - 50;
listBox.w = GetScreen()->w - listBox.x;
listBox.h = font.GetCharH();
serverList.push_back({"foo",{0,0}});
serverList.push_back({"bar",{0,0}});
serverList.push_back({"foobar",{0,0}});
flushNetworkQueue();
beginQueueThread();
BroadcastNetwork();
//ping the network
PingNetwork();
}
Lobby::~Lobby() {
for (auto it : buttonMap) {
delete it.second;
}
#ifdef DEBUG
cout << "leaving Lobby" << endl;
#endif
@@ -67,7 +55,54 @@ void Lobby::FrameStart() {
}
void Lobby::Update(double delta) {
while(HandlePacket(popNetworkPacket()));
Receive();
}
void Lobby::Receive() {
PacketData packet;
while(netUtil->Receive()) {
memcpy(&packet, netUtil->GetInData(), sizeof(PacketData));
switch(packet.type) {
// case PacketList::NONE:
// //
// break;
// case PacketList::PING:
// //
// break;
case PacketList::PONG:
PushServer(&packet);
break;
// case PacketList::JOINREQUEST:
// //
// break;
case PacketList::JOINCONFIRM: {
PacketData p;
memcpy(&p, netUtil->GetInData(), sizeof(PacketData));
*playerID = p.joinConfirm.playerID;
netUtil->Bind(&netUtil->GetInPacket()->address, 0);
SetNextScene(SceneList::INGAME);
}
break;
// case PacketList::DISCONNECT:
// //
// break;
// case PacketList::SYNCHRONIZE:
// //
// break;
#ifdef DEBUG
//this might not be the end of the world; it only happens when the game ping is too low
case PacketList::NEWPLAYER:
cout << "WARNING: new player triggered unexpectedly" << endl;
break;
#endif
// case PacketList::DELETEPLAYER:
// //
// break;
// case PacketList::MOVEMENT:
// //
// break;
}
}
}
void Lobby::FrameEnd() {
@@ -75,18 +110,22 @@ void Lobby::FrameEnd() {
}
void Lobby::Render(SDL_Surface* const screen) {
refreshButton.DrawTo(screen);
joinButton.DrawTo(screen);
backButton.DrawTo(screen);
for (auto it : buttonMap) {
it.second->DrawTo(screen);
}
for (int i = 0; i < serverList.size(); i++) {
if (selectedServer == &serverList[i]) {
//draw the highlight box
SDL_Rect r = listBox;
r.y += i * font.GetCharH();
SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 255, 127, 39));
//draw the server list, highlighting the selected server
SDL_Rect clip;
for (int i = 0; i < serverVector.size(); i++) {
clip = listBox;
clip.y += i * font.GetCharH();
//if a server has been selected, and this is the selected server
if (selectedServer && selectedServer == &serverVector[i]) {
//draw the orange box
SDL_FillRect(screen, &clip, SDL_MapRGB(screen->format, 255, 127, 39));
}
font.DrawStringTo(serverList[i].name, screen, listBox.x, listBox.y + i * font.GetCharH());
font.DrawStringTo(serverVector[i].name, screen, clip.x, clip.y);
}
}
@@ -95,46 +134,32 @@ void Lobby::Render(SDL_Surface* const screen) {
//-------------------------
void Lobby::MouseMotion(SDL_MouseMotionEvent const& motion) {
refreshButton.MouseMotion(motion);
joinButton.MouseMotion(motion);
backButton.MouseMotion(motion);
for (auto it : buttonMap) {
it.second->MouseMotion(motion);
}
}
void Lobby::MouseButtonDown(SDL_MouseButtonEvent const& button) {
refreshButton.MouseButtonDown(button);
joinButton.MouseButtonDown(button);
backButton.MouseButtonDown(button);
for (auto it : buttonMap) {
it.second->MouseButtonDown(button);
}
}
void Lobby::MouseButtonUp(SDL_MouseButtonEvent const& button) {
if (refreshButton.MouseButtonUp(button) == Button::State::HOVER) {
BroadcastNetwork();
selectedServer = nullptr;
if (buttonMap["ping"]->MouseButtonUp(button) == Button::State::HOVER) {
PingNetwork();
}
else if (joinButton.MouseButtonUp(button) == Button::State::HOVER) {
if (selectedServer) {
ConnectToServer(selectedServer);
selectedServer = nullptr;
}
else if (buttonMap["join"]->MouseButtonUp(button) == Button::State::HOVER) {
JoinRequest(selectedServer);
}
else if (backButton.MouseButtonUp(button) == Button::State::HOVER) {
else if (buttonMap["back"]->MouseButtonUp(button) == Button::State::HOVER) {
SetNextScene(SceneList::MAINMENU);
endQueueThread();
selectedServer = nullptr;
}
else if (
//clicked within bounds TODO: make the damn collision system
button.x > listBox.x &&
button.y > listBox.y &&
button.x < listBox.x + listBox.w &&
button.y < listBox.y + (listBox.h * serverList.size())
)
{
//selecting a server
selectedServer = &serverList[(button.y - listBox.y) / listBox.h];
//select a server (clicked within the bounds of the server box)
else if (button.x > listBox.x && button.y > listBox.y && button.y < serverVector.size() * font.GetCharH() + listBox.y) {
selectedServer = &serverVector[(button.y-listBox.y)/font.GetCharH()];
}
else {
//lose focus on a server
selectedServer = nullptr;
}
}
@@ -143,7 +168,7 @@ void Lobby::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE:
SetNextScene(SceneList::MAINMENU);
break;
break;
}
}
@@ -155,80 +180,31 @@ void Lobby::KeyUp(SDL_KeyboardEvent const& key) {
//Utilities
//-------------------------
int Lobby::HandlePacket(Packet p) {
switch(p.meta.type) {
case PacketType::NONE:
//DO NOTHING
return 0;
break;
case PacketType::PING:
//quick pong
p.meta.type = PacketType::PONG;
netUtil->Send(&p.meta.address, &p, sizeof(Packet));
break;
case PacketType::PONG:
//
break;
// case PacketType::BROADCAST_REQUEST:
// //
// break;
case PacketType::BROADCAST_RESPONSE:
PushServer(p.broadcastResponse);
break;
// case PacketType::JOIN_REQUEST:
// //
// break;
case PacketType::JOIN_RESPONSE:
BeginGame(p.joinResponse);
break;
// case PacketType::DISCONNECT:
// //
// 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 Lobby::PingNetwork() {
//ping the network
PacketData p;
p.type = PacketList::PING;
netUtil->Send("255.255.255.255", configUtil->Integer("server.port"), reinterpret_cast<void*>(&p), sizeof(PacketData));
//reset the server list
//TODO: enable this
// serverVector.clear();
}
void Lobby::BroadcastNetwork() {
Packet p;
p.meta.type = PacketType::BROADCAST_REQUEST;
netUtil->Send("255.255.255.255", configUtil->Int("server.port"), &p, sizeof(Packet));
serverList.clear();
void Lobby::PushServer(PacketData* packet) {
ServerData s;
s.name = packet->pong.metadata;
s.address = netUtil->GetInPacket()->address;
serverVector.push_back(s);
}
void Lobby::PushServer(BroadcastResponse& bcast) {
ServerEntry entry;
entry.name = bcast.name;
entry.address = bcast.meta.address;
serverList.push_back(entry);
}
void Lobby::ConnectToServer(ServerEntry* server) {
//_attempt_ to connect to a server
void Lobby::JoinRequest(ServerData* server) {
if (!server) {
throw(runtime_error("No server received"));
//CAN receive null
return;
}
Packet p;
p.meta.type = PacketType::JOIN_REQUEST;
netUtil->Send(&server->address, reinterpret_cast<void*>(&p), sizeof(Packet));
PacketData p;
p.type = PacketList::JOINREQUEST;
snprintf(p.joinRequest.handle, PACKET_STRING_SIZE, "%s", configUtil->CString("handle"));
snprintf(p.joinRequest.avatar, PACKET_STRING_SIZE, "%s", configUtil->CString("avatar"));
netUtil->Send(&server->address, reinterpret_cast<void*>(&p), sizeof(PacketData));
}
void Lobby::BeginGame(JoinResponse& response) {
//should be downloading the resources here as well
infoMgr->SetClientIndex(response.clientIndex);
netUtil->Bind(&response.meta.address, GAME_CHANNEL);
SetNextScene(SceneList::INWORLD);
}
+24 -49
View File
@@ -1,58 +1,31 @@
/* 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 LOBBY_HPP_
#define LOBBY_HPP_
#include "base_scene.hpp"
#include "defines.hpp"
#include "service_locator.hpp"
#include "packet_type.hpp"
#include "network_queue.hpp"
#include "information_manager.hpp"
#include "config_utility.hpp"
#include "surface_manager.hpp"
#include "udp_network_utility.hpp"
#include "button.hpp"
#include "packet_list.hpp"
#include "raster_font.hpp"
#include "button.hpp"
#include <vector>
#include <map>
#include <string>
struct ServerEntry {
std::string name;
IPaddress address;
};
class Lobby : public BaseScene {
public:
//Public access members
Lobby();
Lobby(ConfigUtility*, SurfaceManager*, UDPNetworkUtility*, int* playerID);
~Lobby();
protected:
//Frame loop
void FrameStart();
void Update(double delta);
void Receive();
void FrameEnd();
void Render(SDL_Surface* const);
@@ -64,27 +37,29 @@ protected:
void KeyUp(SDL_KeyboardEvent const&);
//utilities
int HandlePacket(Packet p);
void BroadcastNetwork();
void PushServer(BroadcastResponse&);
void ConnectToServer(ServerEntry*);
void BeginGame(JoinResponse&);
struct ServerData {
std::string name;
IPaddress address;
};
//services
ConfigUtility* configUtil = ServiceLocator<ConfigUtility>::Get();
SurfaceManager* surfaceMgr = ServiceLocator<SurfaceManager>::Get();
UDPNetworkUtility* netUtil = ServiceLocator<UDPNetworkUtility>::Get();
InformationManager* infoMgr = ServiceLocator<InformationManager>::Get();
void PingNetwork();
void PushServer(PacketData*);
void JoinRequest(ServerData*);
//globals
ConfigUtility* configUtil = nullptr;
SurfaceManager* surfaceMgr = nullptr;
UDPNetworkUtility* netUtil = nullptr;
int* playerID;
//members
Button refreshButton;
Button joinButton;
Button backButton;
RasterFont font;
std::map<std::string, Button*> buttonMap;
//the list of servers on the screen
std::vector<ServerData> serverVector;
ServerData* selectedServer = nullptr;
SDL_Rect listBox;
std::vector<ServerEntry> serverList;
ServerEntry* selectedServer = nullptr;
};
#endif
-21
View File
@@ -1,24 +1,3 @@
/* 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 "scene_manager.hpp"
#include <stdexcept>
+34 -39
View File
@@ -1,24 +1,3 @@
/* 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 "main_menu.hpp"
#include <iostream>
@@ -29,16 +8,25 @@ using namespace std;
//Public access members
//-------------------------
MainMenu::MainMenu() {
MainMenu::MainMenu(ConfigUtility* cUtil, SurfaceManager* sMgr) {
#ifdef DEBUG
cout << "entering MainMenu" << endl;
#endif
startButton.Setup(50, 50, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Start");
optionsButton.Setup(50, 100, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Options");
quitButton.Setup(50, 150, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Quit");
configUtil = cUtil;
surfaceMgr = sMgr;
buttonMap["start"] = new Button(50, 50, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Start");
buttonMap["options"] = new Button(50, 100, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Options");
buttonMap["quit"] = new Button(50, 150, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Quit");
buttonMap["testsystems"] = new Button(50, 250, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "TestSystems");
}
MainMenu::~MainMenu() {
for (auto it : buttonMap) {
delete it.second;
}
buttonMap.clear();
#ifdef DEBUG
cout << "leaving MainMenu" << endl;
#endif
@@ -61,9 +49,9 @@ void MainMenu::FrameEnd() {
}
void MainMenu::Render(SDL_Surface* const screen) {
startButton.DrawTo(screen);
optionsButton.DrawTo(screen);
quitButton.DrawTo(screen);
for (auto it : buttonMap) {
it.second->DrawTo(screen);
}
}
//-------------------------
@@ -71,33 +59,40 @@ void MainMenu::Render(SDL_Surface* const screen) {
//-------------------------
void MainMenu::MouseMotion(SDL_MouseMotionEvent const& motion) {
startButton.MouseMotion(motion);
optionsButton.MouseMotion(motion);
quitButton.MouseMotion(motion);
for (auto it : buttonMap) {
it.second->MouseMotion(motion);
}
}
void MainMenu::MouseButtonDown(SDL_MouseButtonEvent const& button) {
startButton.MouseButtonDown(button);
optionsButton.MouseButtonDown(button);
quitButton.MouseButtonDown(button);
for (auto it : buttonMap) {
it.second->MouseButtonDown(button);
}
}
void MainMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) {
if (startButton.MouseButtonUp(button) == Button::State::HOVER) {
if (buttonMap["start"]->MouseButtonUp(button) == Button::State::HOVER) {
SetNextScene(SceneList::LOBBY);
}
if (optionsButton.MouseButtonUp(button) == Button::State::HOVER) {
SetNextScene(SceneList::OPTIONSCREEN);
if (buttonMap["options"]->MouseButtonUp(button) == Button::State::HOVER) {
//TODO
}
if (quitButton.MouseButtonUp(button) == Button::State::HOVER) {
if (buttonMap["quit"]->MouseButtonUp(button) == Button::State::HOVER) {
QuitEvent();
}
if (buttonMap["testsystems"]->MouseButtonUp(button) == Button::State::HOVER) {
SetNextScene(SceneList::TESTSYSTEMS);
}
}
void MainMenu::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE:
QuitEvent();
break;
break;
}
}
void MainMenu::KeyUp(SDL_KeyboardEvent const& key) {
//
}
+15 -30
View File
@@ -1,57 +1,42 @@
/* 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 MAINMENU_HPP_
#define MAINMENU_HPP_
#include "base_scene.hpp"
#include "service_locator.hpp"
#include "config_utility.hpp"
#include "surface_manager.hpp"
#include "button.hpp"
#include <string>
#include <map>
class MainMenu : public BaseScene {
public:
/* Public access members */
MainMenu();
//Public access members
MainMenu(ConfigUtility*, SurfaceManager*);
~MainMenu();
protected:
/* Frame loop */
//Frame loop
void FrameStart();
void Update(double delta);
void FrameEnd();
void Render(SDL_Surface* const);
/* Event handlers */
//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&);
SurfaceManager* surfaceMgr = ServiceLocator<SurfaceManager>::Get();
//globals
ConfigUtility* configUtil;
SurfaceManager* surfaceMgr;
Button startButton;
Button optionsButton;
Button quitButton;
//members
std::map<std::string, Button*> buttonMap;
};
#endif
+4 -6
View File
@@ -1,19 +1,17 @@
#config
LIBDIR=../libs
LOCALLIBS=$(LIBDIR)/out/libCodebase.a $(LIBDIR)/out/libCommon.a
LIB=$(LOCALLIBS) -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL
INCLUDES=$(LIBDIR)/Codebase $(LIBDIR)/common
INCLUDES=../common
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
LIB=../common/out/common.a -lmingw32 -lSDL_net -lSDLmain -lSDL -lwsock32 -liphlpapi
#source
SRC=$(wildcard *.cpp)
SRC=$(filter-out unit.cpp, $(wildcard *.cpp))
#objects
OBJDIR=obj
OBJ=$(addprefix $(OBJDIR)/,$(SRC:.cpp=.o))
#output
OUTDIR=../out
OUTDIR=out
OUT=$(addprefix $(OUTDIR)/,client)
#targets
-77
View File
@@ -1,77 +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.
*/
#include "option_screen.hpp"
#include <iostream>
using namespace std;
//-------------------------
//Public access members
//-------------------------
OptionScreen::OptionScreen() {
#ifdef DEBUG
cout << "entering OptionScreen" << endl;
#endif
backButton.Setup(50, 50, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Back");
}
OptionScreen::~OptionScreen() {
#ifdef DEBUG
cout << "leaving OptionScreen" << endl;
#endif
}
//-------------------------
//Frame loop
//-------------------------
void OptionScreen::Render(SDL_Surface* const screen) {
backButton.DrawTo(screen);
}
//-------------------------
//Event handlers
//-------------------------
void OptionScreen::MouseMotion(SDL_MouseMotionEvent const& motion) {
backButton.MouseMotion(motion);
}
void OptionScreen::MouseButtonDown(SDL_MouseButtonEvent const& button) {
backButton.MouseButtonDown(button);
}
void OptionScreen::MouseButtonUp(SDL_MouseButtonEvent const& button) {
if (backButton.MouseButtonUp(button) == Button::State::HOVER) {
SetNextScene(SceneList::MAINMENU);
}
}
void OptionScreen::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE:
SetNextScene(SceneList::MAINMENU);
break;
}
}
-51
View File
@@ -1,51 +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 OPTIONSCREEN_HPP_
#define OPTIONSCREEN_HPP_
#include "base_scene.hpp"
#include "service_locator.hpp"
#include "surface_manager.hpp"
#include "button.hpp"
class OptionScreen : public BaseScene {
public:
/* Public access members */
OptionScreen();
~OptionScreen();
protected:
/* Frame loop */
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&);
SurfaceManager* surfaceMgr = ServiceLocator<SurfaceManager>::Get();
Button backButton;
};
#endif
+93
View File
@@ -0,0 +1,93 @@
#include "player.hpp"
#define ANIMATION_SPEED 0.1
#define WALKING_SPEED 140
Player::Player(SDL_Surface* s, int w, int h)
: sprite(s, w, h)
{
}
void Player::Update(double delta) {
if (motion.y > 0) {
FaceDirection(Direction::SOUTH);
}
else if (motion.y < 0) {
FaceDirection(Direction::NORTH);
}
else if (motion.x < 0) {
FaceDirection(Direction::WEST);
}
else if (motion.x > 0) {
FaceDirection(Direction::EAST);
}
if (motion.x != 0 && motion.y != 0) {
sprite.SetInterval(ANIMATION_SPEED);
constexpr double d = 1/sqrt(2);
position += motion * d * delta;
}
else if (motion != 0) {
sprite.SetInterval(ANIMATION_SPEED);
position += motion * delta;
}
else {
sprite.SetCurrentFrame(0);
sprite.SetInterval(0);
}
sprite.Update(delta);
}
void Player::WalkInDirection(Direction d) {
switch(d) {
case Direction::NORTH:
if (motion.y >= 0) {
motion.y -= WALKING_SPEED;
}
else {
motion.y = -WALKING_SPEED;
}
break;
case Direction::SOUTH:
if (motion.y <= 0) {
motion.y += WALKING_SPEED;
}
else {
motion.y = WALKING_SPEED;
}
break;
case Direction::WEST:
if (motion.x >= 0) {
motion.x -= WALKING_SPEED;
}
else {
motion.x = -WALKING_SPEED;
}
break;
case Direction::EAST:
if (motion.x <= 0) {
motion.x += WALKING_SPEED;
}
else {
motion.x = WALKING_SPEED;
}
break;
}
}
void Player::FaceDirection(Direction dir) {
switch(dir) {
case Direction::SOUTH:
sprite.SetCurrentStrip(0);
break;
case Direction::NORTH:
sprite.SetCurrentStrip(1);
break;
case Direction::WEST:
sprite.SetCurrentStrip(2);
break;
case Direction::EAST:
sprite.SetCurrentStrip(3);
break;
}
}
+36
View File
@@ -0,0 +1,36 @@
#ifndef PLAYER_HPP_
#define PLAYER_HPP_
#include "defines.hpp"
#include "vector2.hpp"
#include "sprite_sheet.hpp"
#include "SDL/SDL.h"
class Player {
public:
Player(SDL_Surface*, int w, int h);
void Update(double delta);
void WalkInDirection(Direction);
Vector2 SetPosition(Vector2 v) { return position = v; }
Vector2 ShiftPosition(Vector2 v) { return position += v; }
Vector2 GetPosition() const { return position; };
Vector2 SetMotion(Vector2 v) { return motion = v; }
Vector2 ShiftMotion(Vector2 v) { return motion += v; }
Vector2 GetMotion() const { return motion; }
void DrawTo(SDL_Surface* const s) { sprite.DrawTo(s, position.x, position.y); }
void FaceDirection(Direction);
SpriteSheet* GetSpriteSheet() { return &sprite; };
private:
Vector2 position;
Vector2 motion;
SpriteSheet sprite;
};
#endif
+53
View File
@@ -0,0 +1,53 @@
#include "player_manager.hpp"
#include <stdexcept>
PlayerManager::PlayerManager() {
//
}
PlayerManager::~PlayerManager() {
DeleteAll();
}
Player* PlayerManager::New(int index, SDL_Surface* avatarSheet) {
if (playerMap.find(index) != playerMap.end()) {
throw(std::runtime_error("This player's index is already taken"));
}
return playerMap[index] = new Player(avatarSheet, avatarSheet->w/4, avatarSheet->h/4);
}
Player* PlayerManager::Get(int index) {
std::map<int, Player*>::iterator it = playerMap.find(index);
if(it == playerMap.end()) {
throw(std::runtime_error("Failed to find a player with that index"));
}
return it->second;
}
void PlayerManager::Delete(int index) {
std::map<int, Player*>::iterator it = playerMap.find(index);
delete it->second;
playerMap.erase(it);
}
void PlayerManager::UpdateAll(double delta) {
for (auto it : playerMap) {
it.second->Update(delta);
}
}
void PlayerManager::DrawAllTo(SDL_Surface* dest) {
for (auto it : playerMap) {
it.second->DrawTo(dest);
}
}
void PlayerManager::DeleteAll() {
for (auto it : playerMap) {
delete it.second;
}
playerMap.clear();
}
+26
View File
@@ -0,0 +1,26 @@
#ifndef PLAYERMANAGER_HPP_
#define PLAYERMANAGER_HPP_
#include "player.hpp"
#include <map>
class PlayerManager {
public:
PlayerManager();
~PlayerManager();
Player* New(int index, SDL_Surface* avatarSheet);
Player* Get(int index);
void Delete(int index);
void UpdateAll(double delta);
void DrawAllTo(SDL_Surface* dest);
void DeleteAll();
Player* operator[](int i) { return Get(i); }
private:
std::map<int, Player*> playerMap;
};
#endif
+8 -27
View File
@@ -1,40 +1,21 @@
/* 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,
QUIT, //doubles as "up one scene" in nested scenes
CONTINUE,
FIRST,
//custom indexes
INCOMBAT,
INWORLD,
LOBBY,
TESTSYSTEMS,
SPLASH,
MAINMENU,
OPTIONSCREEN,
SPLASHSCREEN,
INGAME,
//subscenes
LOBBY,
COMBAT,
};
#endif
+24 -91
View File
@@ -1,24 +1,3 @@
/* 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 "scene_manager.hpp"
#include <stdexcept>
@@ -29,12 +8,12 @@
//-------------------------
//Add the custom scene headers here
#include "in_combat.hpp"
#include "in_world.hpp"
#include "lobby.hpp"
#include "test_systems.hpp"
#include "splash.hpp"
#include "main_menu.hpp"
#include "option_screen.hpp"
#include "splash_screen.hpp"
#include "lobby.hpp"
#include "in_game.hpp"
//-------------------------
//Public access members
@@ -48,30 +27,7 @@ SceneManager::~SceneManager() {
UnloadScene();
}
/* SceneManager::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 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() {
//load the config file
try {
configUtil = ServiceLocator<ConfigUtility>::Set(new ConfigUtility());
configUtil->Load("rsc/config.cfg");
}
catch(std::runtime_error& e) {
std::string s = e.what();
s += "; Ensure that the \"rsc\" directory is present";
throw(std::runtime_error(s));
}
//initialize the APIs
if (SDL_Init(SDL_INIT_VIDEO)) {
throw(std::runtime_error("Failed to initialize SDL"));
}
@@ -79,23 +35,15 @@ void SceneManager::Init() {
throw(std::runtime_error("Failed to initialize SDL_net"));
}
//create the screen
Uint32 flags = SDL_HWSURFACE | SDL_DOUBLEBUF;
flags |= configUtil->Bool("screen.f") ? SDL_FULLSCREEN : 0;
configUtil.Load("rsc/config.cfg");
netUtil.Open(0, sizeof(PacketData));
BaseScene::SetScreen(
configUtil->Int("screen.w"),
configUtil->Int("screen.h"),
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
netUtil->Open(0, sizeof(Packet));
//set the screen from the config file
int flags = SDL_HWSURFACE|SDL_DOUBLEBUF;
if (configUtil.Boolean("screen.f")) {
flags |= SDL_FULLSCREEN;
}
BaseScene::SetScreen(configUtil.Integer("screen.w"),configUtil.Integer("screen.h"),0,flags);
}
void SceneManager::Proc() {
@@ -137,20 +85,7 @@ void SceneManager::Proc() {
}
void SceneManager::Quit() {
//clean up the services
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();
//deinitialize the APIs
SDLNet_Quit();
SDL_Quit();
}
@@ -164,24 +99,22 @@ void SceneManager::LoadScene(SceneList sceneIndex) {
switch(sceneIndex) {
//add scene creation calls here
case SceneList::INCOMBAT:
activeScene = new InCombat();
case SceneList::TESTSYSTEMS:
activeScene = new TestSystems(&configUtil, &surfaceMgr, &netUtil);
break;
case SceneList::INWORLD:
activeScene = new InWorld();
break;
case SceneList::LOBBY:
activeScene = new Lobby();
case SceneList::FIRST:
case SceneList::SPLASH:
activeScene = new Splash(&configUtil, &surfaceMgr);
break;
case SceneList::MAINMENU:
activeScene = new MainMenu();
activeScene = new MainMenu(&configUtil, &surfaceMgr);
break;
case SceneList::OPTIONSCREEN:
activeScene = new OptionScreen();
case SceneList::LOBBY:
activeScene = new Lobby(&configUtil, &surfaceMgr, &netUtil, &playerID);
break;
case SceneList::FIRST:
case SceneList::SPLASHSCREEN:
activeScene = new SplashScreen();
case SceneList::INGAME:
activeScene = new InGame(&configUtil, &surfaceMgr, &netUtil, &playerID);
break;
default:
+8 -30
View File
@@ -1,42 +1,19 @@
/* 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 SCENEMANAGER_HPP_
#define SCENEMANAGER_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 "packet_list.hpp"
#include "SDL/SDL.h"
class SceneManager {
public:
/* Public access members */
//Public access members
SceneManager();
~SceneManager();
@@ -45,16 +22,17 @@ public:
void Quit();
private:
/* Private access members */
//Private access members
void LoadScene(SceneList sceneIndex);
void UnloadScene();
BaseScene* activeScene = nullptr;
ConfigUtility* configUtil = nullptr;
SurfaceManager* surfaceMgr = nullptr;
UDPNetworkUtility* netUtil = nullptr;
InformationManager* infoMgr = nullptr;
//globals
ConfigUtility configUtil;
SurfaceManager surfaceMgr;
UDPNetworkUtility netUtil;
int playerID = -1;
};
#endif
+62
View File
@@ -0,0 +1,62 @@
#include "splash.hpp"
#include <iostream>
using namespace std;
//-------------------------
//Public access members
//-------------------------
Splash::Splash(ConfigUtility* cUtil, SurfaceManager* sMgr) {
#ifdef DEBUG
cout << "entering Splash" << endl;
#endif
configUtil = cUtil;
surfaceMgr = sMgr;
logo = new Image(surfaceMgr->Load("splash-logo", configUtil->String("logos") + "/krstudios.bmp"));
}
Splash::~Splash() {
delete logo;
surfaceMgr->Free("splash-logo");
#ifdef DEBUG
cout << "leaving Splash" << endl;
#endif
}
void Splash::RunFrame(double delta) {
//skip any event handling here
SDL_Event event;
while(SDL_PollEvent(&event));
//draw the logo in the middle of the screen
int x = (GetScreen()->w - logo->GetClipW()) / 2;
int y = (GetScreen()->h - logo->GetClipH()) / 2;
logo->DrawTo(GetScreen(),x,y);
SDL_Flip(GetScreen());
//load the resources ONCE
if (!loaded) {
loaded = true;
LoadResources();
}
//wait X seconds
if (Clock::now() - start > std::chrono::duration<int>(1)) {
SetNextScene(SceneList::MAINMENU);
}
}
void Splash::LoadResources() {
//load the global resources here
surfaceMgr->Load("font", configUtil->String("fonts") + "/pokemon_dark_font.bmp");
surfaceMgr->Load("button", configUtil->String("interface") + "/button.bmp");
surfaceMgr->Load("elliot", configUtil->String("sprites") + "/elliot2.bmp");
surfaceMgr->Load("coa", configUtil->String("sprites") + "/coa2.bmp");
surfaceMgr->Load("flower", configUtil->String("sprites") + "/aniflower.bmp");
surfaceMgr->Load("terrain", configUtil->String("tilesets") + "/terrain.bmp");
//TODO
}
+34
View File
@@ -0,0 +1,34 @@
#ifndef SPLASH_HPP_
#define SPLASH_HPP_
#include "base_scene.hpp"
#include "config_utility.hpp"
#include "surface_manager.hpp"
#include "image.hpp"
#include <chrono>
class Splash : public BaseScene {
public:
Splash(ConfigUtility*, SurfaceManager*);
~Splash();
protected:
typedef std::chrono::high_resolution_clock Clock;
void RunFrame(double delta);
void RenderFrame() {};
void LoadResources();
//globals
ConfigUtility* configUtil;
SurfaceManager* surfaceMgr;
//members
bool loaded = false;
Clock::time_point start = Clock::now();
Image* logo = nullptr;
};
#endif
-86
View File
@@ -1,86 +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.
*/
#include "splash_screen.hpp"
#include <iostream>
using namespace std;
//-------------------------
//Public access members
//-------------------------
SplashScreen::SplashScreen() {
#ifdef DEBUG
cout << "entering SplashScreen" << endl;
#endif
logo.SetSurface(surfaceMgr->Load("splash-logo", configUtil->String("logos") + "/krstudios.bmp"));
}
SplashScreen::~SplashScreen() {
surfaceMgr->Free("splash-logo");
#ifdef DEBUG
cout << "leaving SplashScreen" << endl;
#endif
}
//-------------------------
//Frame loop
//-------------------------
void SplashScreen::RunFrame(double delta) {
HandleEvents();
if (!loaded) {
//never repeat this
loaded = true;
//quick draw
RenderFrame();
LoadResources();
}
if (Clock::now() - start > std::chrono::duration<int>(1)) {
SetNextScene(SceneList::MAINMENU);
}
}
void SplashScreen::RenderFrame() {
SDL_FillRect(GetScreen(), 0, 0);
int x = (GetScreen()->w - logo.GetClipW()) / 2;
int y = (GetScreen()->h - logo.GetClipH()) / 2;
logo.DrawTo(GetScreen(), x, y);
SDL_Flip(GetScreen());
}
void SplashScreen::LoadResources() {
//standard
surfaceMgr->Load("font", configUtil->String("fonts") + "/pokemon_dark_font.bmp");
surfaceMgr->Load("button", configUtil->String("interface") + "/button.bmp");
//debugging
surfaceMgr->Load("elliot", configUtil->String("sprites") + "/elliot2.bmp");
surfaceMgr->Load("coa", configUtil->String("sprites") + "/coa2.bmp");
surfaceMgr->Load("flower", configUtil->String("sprites") + "/aniflower.bmp");
surfaceMgr->Load("terrain", configUtil->String("tilesets") + "/terrain.bmp");
//TODO
}
-54
View File
@@ -1,54 +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 SPLASHSCREEN_HPP_
#define SPLASHSCREEN_HPP_
#include "base_scene.hpp"
#include "defines.hpp"
#include "service_locator.hpp"
#include "config_utility.hpp"
#include "surface_manager.hpp"
#include "image.hpp"
#include <chrono>
class SplashScreen : public BaseScene {
public:
/* Public access members */
SplashScreen();
~SplashScreen();
protected:
/* Frame loop */
void RunFrame(double delta);
void RenderFrame();
void LoadResources();
bool loaded = false;
ConfigUtility* configUtil = ServiceLocator<ConfigUtility>::Get();
SurfaceManager* surfaceMgr = ServiceLocator<SurfaceManager>::Get();
Image logo;
Clock::time_point start = Clock::now();
};
#endif
+170
View File
@@ -0,0 +1,170 @@
#include "test_systems.hpp"
#include <iostream>
using namespace std;
#include "splash.hpp"
//-------------------------
//Public access members
//-------------------------
TestSystems::TestSystems(ConfigUtility* cUtil, SurfaceManager* sMgr, UDPNetworkUtility* nUtil) {
#ifdef DEBUG
cout << "entering TestSystems" << endl;
#endif
configUtil = cUtil;
surfaceMgr = sMgr;
netUtil = nUtil;
playerCounter = currentPlayer = 0;
playerMgr.New(playerCounter++, surfaceMgr->Get("elliot"));
playerMgr.New(playerCounter++, surfaceMgr->Get("elliot"));
playerMgr.New(playerCounter++, surfaceMgr->Get("coa"));
playerMgr.New(playerCounter++, surfaceMgr->Get("coa"));
font.SetSurface(surfaceMgr->Get("font"));
}
TestSystems::~TestSystems() {
playerMgr.DeleteAll();
#ifdef DEBUG
cout << "leaving TestSystems" << endl;
#endif
}
//-------------------------
//Frame loop
//-------------------------
void TestSystems::FrameStart() {
//
}
void TestSystems::Update(double delta) {
playerMgr.UpdateAll(delta);
}
void TestSystems::FrameEnd() {
//
}
string IToS(int i) {
char buffer[20];
memset(buffer, 0, 20);
sprintf(buffer, "%d", i);
return string(buffer);
}
void TestSystems::Render(SDL_Surface* const screen) {
FrameRate::Calculate();
playerMgr.DrawAllTo(screen);
font.DrawStringTo("FPS: " + IToS(FrameRate::GetFrameRate()), screen, 16, 16);
}
//-------------------------
//Event handlers
//-------------------------
void TestSystems::MouseMotion(SDL_MouseMotionEvent const& motion) {
//
}
void TestSystems::MouseButtonDown(SDL_MouseButtonEvent const& button) {
//
}
void TestSystems::MouseButtonUp(SDL_MouseButtonEvent const& button) {
//
}
void TestSystems::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE:
SetNextScene(SceneList::MAINMENU);
break;
case SDLK_w:
playerMgr[currentPlayer]->WalkInDirection(Direction::NORTH);
SendMessage("move up");
break;
case SDLK_s:
playerMgr[currentPlayer]->WalkInDirection(Direction::SOUTH);
SendMessage("move down");
break;
case SDLK_a:
playerMgr[currentPlayer]->WalkInDirection(Direction::WEST);
SendMessage("move left");
break;
case SDLK_d:
playerMgr[currentPlayer]->WalkInDirection(Direction::EAST);
SendMessage("move right");
break;
case SDLK_1:
SwitchToPlayer(0);
break;
case SDLK_2:
SwitchToPlayer(1);
break;
case SDLK_3:
SwitchToPlayer(2);
break;
case SDLK_4:
SwitchToPlayer(3);
break;
}
}
void TestSystems::KeyUp(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_w:
playerMgr[currentPlayer]->WalkInDirection(Direction::SOUTH);
break;
case SDLK_s:
playerMgr[currentPlayer]->WalkInDirection(Direction::NORTH);
break;
case SDLK_a:
playerMgr[currentPlayer]->WalkInDirection(Direction::EAST);
break;
case SDLK_d:
playerMgr[currentPlayer]->WalkInDirection(Direction::WEST);
break;
}
}
//-------------------------
//Utilities
//-------------------------
void TestSystems::NewPlayer(int index, std::string avatarName, int x, int y) {
Player* p = playerMgr.New(index, surfaceMgr->Get(avatarName));
p->SetPosition(Vector2(x, y));
}
void TestSystems::SwitchToPlayer(int index) {
//dirty hacks for smooth movement
playerMgr[currentPlayer]->SetMotion(Vector2(0,0));
currentPlayer = index;
Uint8* key = SDL_GetKeyState(nullptr);
if (key[SDLK_w]) {
playerMgr[currentPlayer]->WalkInDirection(Direction::NORTH);
}
if (key[SDLK_s]) {
playerMgr[currentPlayer]->WalkInDirection(Direction::SOUTH);
}
if (key[SDLK_a]) {
playerMgr[currentPlayer]->WalkInDirection(Direction::WEST);
}
if (key[SDLK_d]) {
playerMgr[currentPlayer]->WalkInDirection(Direction::EAST);
}
}
void TestSystems::SendMessage(std::string s) {
cout << s << endl;
}
+54
View File
@@ -0,0 +1,54 @@
#ifndef TESTSYSTEMS_HPP_
#define TESTSYSTEMS_HPP_
#include "base_scene.hpp"
#include "config_utility.hpp"
#include "surface_manager.hpp"
#include "udp_network_utility.hpp"
#include "packet_list.hpp"
#include "player_manager.hpp"
#include "frame_rate.hpp"
#include "raster_font.hpp"
#include <string>
class TestSystems : public BaseScene {
public:
//Public access members
TestSystems(ConfigUtility*, SurfaceManager*, UDPNetworkUtility*);
~TestSystems();
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&);
//utilities
void NewPlayer(int index, std::string avatarName, int x, int y);
void SwitchToPlayer(int index);
void SendMessage(std::string);
//members
ConfigUtility* configUtil = nullptr;
SurfaceManager* surfaceMgr = nullptr;
UDPNetworkUtility* netUtil = nullptr;
PlayerManager playerMgr;
RasterFont font;
int playerCounter;
int currentPlayer;
};
#endif
+7
View File
@@ -0,0 +1,7 @@
#include <iostream>
using namespace std;
int SDL_main(int argc, char* argv[]) {
return 0;
}
@@ -23,13 +23,15 @@
#include <stdexcept>
Button::Button(Sint16 i, Sint16 j, SDL_Surface* imageSurface, SDL_Surface* fontSurface, std::string s) {
Setup(i, j, imageSurface, fontSurface, s);
Button::Button():
Button(0,0, nullptr, nullptr)
{
}
void Button::Setup(Sint16 i, Sint16 j, SDL_Surface* imageSurface, SDL_Surface* fontSurface, std::string s) {
Button::Button(Sint16 i, Sint16 j, SDL_Surface* imageSurface, SDL_Surface* fontSurface, std::string s) {
x = i;
y = j;
state = State::NORMAL;
SetSurfaces(imageSurface, fontSurface);
@@ -34,11 +34,9 @@ public:
NORMAL, HOVER, PRESSED
};
Button() = default;
Button();
Button(Sint16 x, Sint16 y, SDL_Surface* imageSurface, SDL_Surface* fontSurface, std::string text = "");
void Setup(Sint16 x, Sint16 y, SDL_Surface* imageSurface, SDL_Surface* fontSurface, std::string text = "");
//return the current state
State MouseMotion(SDL_MouseMotionEvent const&);
State MouseButtonDown(SDL_MouseButtonEvent const&);
@@ -71,11 +69,11 @@ public:
private:
State CalcState(Sint16 x, Sint16 y, bool leftPressed);
Sint16 x = 0, y = 0;
Sint16 textX = 0, textY = 0; //prevent recalc every loop
Sint16 x, y;
Sint16 textX, textY; //prevent recalc every loop
Image image;
RasterFont font;
State state = State::NORMAL;
State state;
std::string text;
};
+3 -5
View File
@@ -1,9 +1,7 @@
#config
LIBDIR=..
LOCALLIBS=
LIB=
INCLUDES=
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
LIB=
#source
SRC=$(wildcard *.cpp)
@@ -13,8 +11,8 @@ OBJDIR=obj
OBJ=$(addprefix $(OBJDIR)/,$(SRC:.cpp=.o))
#output
OUTDIR=../out
OUT=$(addprefix $(OUTDIR)/,libCodebase.a)
OUTDIR=out
OUT=$(addprefix $(OUTDIR)/,common.a)
#targets
all: $(OBJ) $(OUT)
+109
View File
@@ -0,0 +1,109 @@
#ifndef PACKETLIST_HPP_
#define PACKETLIST_HPP_
#include "vector2.hpp"
#include <string>
#define PACKET_STRING_SIZE 100
enum class PacketList {
NONE = 0,
//connections
PING = 1,
PONG = 2,
JOINREQUEST = 3,
JOINCONFIRM = 4,
DISCONNECT = 5,
//information control
SYNCHRONIZE = 6,
NEWPLAYER = 7,
DELETEPLAYER = 8,
MOVEMENT = 9,
};
//-------------------------
//connections
//-------------------------
struct Ping {
PacketList type = PacketList::PING;
char metadata[PACKET_STRING_SIZE];
};
struct Pong {
PacketList type = PacketList::PONG;
char metadata[PACKET_STRING_SIZE];
};
struct JoinRequest {
PacketList type = PacketList::JOINREQUEST;
char handle[PACKET_STRING_SIZE];
char avatar[PACKET_STRING_SIZE];
};
struct JoinConfirm {
PacketList type = PacketList::JOINCONFIRM;
int playerID;
};
struct Disconnect {
PacketList type = PacketList::DISCONNECT;
int playerID;
};
//-------------------------
//information control
//-------------------------
struct Synchronize {
PacketList type = PacketList::SYNCHRONIZE;
int playerID;
};
struct NewPlayer {
PacketList type = PacketList::NEWPLAYER;
int playerID;
char handle[PACKET_STRING_SIZE];
char avatar[PACKET_STRING_SIZE];
Vector2 position;
Vector2 motion;
};
struct DeletePlayer {
PacketList type = PacketList::DELETEPLAYER;
int playerID;
};
struct Movement {
PacketList type = PacketList::MOVEMENT;
int playerID;
Vector2 position;
Vector2 motion;
};
//-------------------------
//the packet itself
//-------------------------
union PacketData {
PacketData() {};
PacketList type = PacketList::NONE;
//connections
Ping ping;
Pong pong;
JoinRequest joinRequest;
JoinConfirm joinConfirm;
Disconnect disconnect;
//information control
Synchronize synchronize;
NewPlayer newPlayer;
DeletePlayer deletePlayer;
Movement movement;
};
#endif
+3 -5
View File
@@ -1,9 +1,7 @@
#config
LIBDIR=..
LOCALLIBS=
LIB=
INCLUDES=
CFLAGS+=$(addprefix -I,$(INCLUDES))
LIB=
#source
SRC=$(wildcard *.c)
@@ -13,7 +11,7 @@ OBJDIR=obj
OBJ=$(addprefix $(OBJDIR)/,$(SRC:.c=.o))
#output
OUTDIR=../out
OUTDIR=out
OUT=$(addprefix $(OUTDIR)/,libSDL_net.a)
#targets
@@ -36,4 +34,4 @@ $(OBJDIR)/%.o: %.c
clean:
$(RM) *.o *.a *.exe
rebuild: clean all
rebuild: clean all
-30
View File
@@ -1,30 +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.
*/
#include "defines.hpp"
#include <cstdio>
std::string itos(int i) {
char buffer[20];
snprintf(buffer, 20, "%d", i);
return std::string(buffer);
}
-35
View File
@@ -1,35 +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 DEFINES_HPP_
#define DEFINES_HPP
#include <chrono>
#include <string>
#define GAME_CHANNEL 0
#define CHAT_CHANNEL 1
typedef std::chrono::high_resolution_clock Clock;
std::string itos(int i);
#endif
-39
View File
@@ -1,39 +0,0 @@
#config
LIBDIR=..
LOCALLIBS=$(LIBDIR)/out/libCodebase.a
LIB=
INCLUDES=$(LIBDIR)/Codebase
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)/,libCommon.a)
#targets
all: $(OBJ) $(OUT)
ar -crs $(OUT) $(OBJ)
$(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
-110
View File
@@ -1,110 +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.
*/
#include "network_queue.hpp"
#include "service_locator.hpp"
#include "udp_network_utility.hpp"
#include "SDL/SDL_thread.h"
#include <stdexcept>
#include <deque>
static SDL_sem* lock = SDL_CreateSemaphore(1);
static SDL_Thread* queueThread = nullptr;
static std::deque<Packet> queue;
static bool running = false;
static int networkQueue(void*) {
UDPNetworkUtility* netUtil = ServiceLocator<UDPNetworkUtility>::Get();
while(running) {
SDL_SemWait(lock);
while(netUtil->Receive()) {
Packet p;
memcpy(&p, netUtil->GetInData(), sizeof(Packet));
p.meta.address = netUtil->GetInPacket()->address;
queue.push_back(p);
}
SDL_SemPost(lock);
SDL_Delay(10);
}
return 0;
}
void beginQueueThread() {
if (running) {
return;
}
running = true;
if (!(queueThread = SDL_CreateThread(networkQueue, nullptr))) {
throw(std::runtime_error("Failed to create the network thread"));
}
}
void endQueueThread() {
if (!running) {
return;
}
running = false;
SDL_WaitThread(queueThread, nullptr);
queueThread = nullptr;
}
void killQueueThread() {
if (!running) {
return;
}
running = false;
SDL_KillThread(queueThread);
queueThread = nullptr;
}
Packet peekNetworkPacket() {
SDL_SemWait(lock);
Packet p;
if (queue.size() > 0) {
Packet p = queue[0];
}
SDL_SemPost(lock);
return p;
}
Packet popNetworkPacket() {
SDL_SemWait(lock);
Packet p;
if (queue.size() > 0) {
p = queue[0];
queue.pop_front();
}
SDL_SemPost(lock);
return p;
}
void flushNetworkQueue() {
UDPNetworkUtility* netUtil = ServiceLocator<UDPNetworkUtility>::Get();
SDL_SemWait(lock);
while(netUtil->Receive());
queue.clear();
SDL_SemPost(lock);
}
-34
View File
@@ -1,34 +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 NETWORKQUEUE_HPP_
#define NETWORKQUEUE_HPP_
#include "packet_type.hpp"
void beginQueueThread();
void endQueueThread();
void killQueueThread();
Packet peekNetworkPacket();
Packet popNetworkPacket();
void flushNetworkQueue();
#endif
-138
View File
@@ -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
-42
View File
@@ -1,42 +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 SERVICELOCATOR_HPP_
#define SERVICELOCATOR_HPP_
template<typename T>
class ServiceLocator {
public:
static T* Set(T* t) {
delete service;
return service = t;
}
static T* Get() {
return service;
}
private:
static T* service;
};
template<typename T>
T* ServiceLocator<T>::service = nullptr;
#endif
-14
View File
@@ -1,14 +0,0 @@
OUTDIR=out
all: $(OUTDIR)
$(MAKE) -C SDL_net
$(MAKE) -C codebase
$(MAKE) -C common
$(OUTDIR):
mkdir $(OUTDIR)
clean:
$(RM) *.o *.a *.exe
rebuild: clean all
-15
View File
@@ -1,15 +0,0 @@
OUTDIR=out
all: $(OUTDIR)
$(MAKE) -C libs
$(MAKE) -C server
$(MAKE) -C client
$(MAKE) -C test
$(OUTDIR):
mkdir $(OUTDIR)
clean:
$(RM) *.o *.a *.exe
rebuild: clean all
+3 -4
View File
@@ -1,8 +1,6 @@
#configuration of the programs
#configuration of the program
server.host = 127.0.0.1
server.port = 1991
server.name = foobar
server.port = 2000
screen.w = 800
screen.h = 600
screen.f = false
@@ -18,3 +16,4 @@ interface = rsc/graphics/interface
debug = true
avatar = elliot2.bmp
handle = UserName
servername = foobar
Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

+32
View File
@@ -0,0 +1,32 @@
#ifndef CLIENTDATA_HPP_
#define CLIENTDATA_HPP_
#include "vector2.hpp"
#include <string>
struct ClientData {
ClientData() = default;
ClientData(int ID, int ch, std::string h, std::string a) {
playerID = ID;
channel = ch;
handle = h;
avatar = a;
}
void Update(double delta) {
position += motion * delta;
}
int playerID = -1;
int channel = -1;
Vector2 position;
Vector2 motion;
std::string handle;
std::string avatar;
enum class Command {
NORMAL,
CHANGED,
}command = Command::NORMAL;
};
#endif
-21
View File
@@ -1,24 +1,3 @@
/* 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 "server_application.hpp"
#include <stdexcept>
+11 -9
View File
@@ -1,24 +1,26 @@
#config
LIBDIR=../libs
LOCALLIBS=$(LIBDIR)/out/libCodebase.a $(LIBDIR)/out/libCommon.a
LIB=$(LOCALLIBS) -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL
INCLUDES=$(LIBDIR)/Codebase $(LIBDIR)/common
INCLUDES=../common
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
LIB=../common/out/common.a -lmingw32 -lSDL_net -lSDLmain -lSDL -lwsock32 -liphlpapi
#source
SRC=$(wildcard *.cpp)
SRC=$(filter-out unit.cpp main.cpp, $(wildcard *.cpp))
#objects
OBJDIR=obj
OBJ=$(addprefix $(OBJDIR)/,$(SRC:.cpp=.o))
#output
OUTDIR=../out
OUT=$(addprefix $(OUTDIR)/,server)
OUTDIR=out
#targets
all: $(OBJ) $(OUT)
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIB)
all: server unit
server: $(OBJ) $(OUT)
$(CXX) $(CXXFLAGS) -o $(OUTDIR)/$@ main.cpp $(OBJ) $(LIB)
unit: $(OBJ) $(OUT)
$(CXX) $(CXXFLAGS) -o $(OUTDIR)/$@ unit.cpp $(OBJ) $(LIB)
$(OBJ): | $(OBJDIR)
+144 -187
View File
@@ -1,24 +1,3 @@
/* 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 "server_application.hpp"
#include <stdexcept>
@@ -26,203 +5,181 @@
using namespace std;
//-------------------------
//Public access members
//-------------------------
ServerApplication::ServerApplication() {
//
}
ServerApplication::~ServerApplication() {
//
}
/* ServerApplication::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 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) {
std::string s = e.what();
s += "; Ensure that the \"rsc\" directory is present";
throw(std::runtime_error(s));
}
//check the port is valid
if (configUtil->Int("server.port") <= 0) {
throw(runtime_error("Cannot open the server on an invalid port or port 0"));
}
//initialize the APIs
if (SDLNet_Init()) {
throw(runtime_error("Failed to initialize SDL_net"));
}
//instanciate the remaining services
netUtil = ServiceLocator<UDPNetworkUtility>::Set(new UDPNetworkUtility());
//initiate the remaining services
netUtil->Open(configUtil->Int("server.port"), sizeof(Packet));
//create the threads
beginQueueThread();
//output the server information
cout << configUtil->String("server.name") << endl;
cout << "Open on port " << configUtil->String("server.port") << endl;
//disable this for debugging
configUtil.Load("config.cfg");
netUtil.Open(configUtil.Integer("server.port"), sizeof(PacketData));
running = true;
}
void ServerApplication::Proc() {
Clock::duration delta = Clock::now() - lastTick;
lastTick = Clock::now();
while(running) {
try {
//process all packets on the network queue
while(HandlePacket(popNetworkPacket()));
//handle input
while(netUtil.Receive()) {
PacketData packet;
memcpy(reinterpret_cast<void*>(&packet), netUtil.GetInData(), sizeof(PacketData));
switch(packet.type) {
// case PacketList::NONE:
// //
// break;
case PacketList::PING:
Ping(&packet);
break;
// case PacketList::PONG:
// //
// break;
case PacketList::JOINREQUEST:
JoinRequest(&packet);
break;
// case PacketList::JOINCONFIRM:
// //
// break;
case PacketList::DISCONNECT:
Disconnect(packet.disconnect.playerID);
break;
// case PacketList::SYNCHRONIZE:
// //
// break;
// case PacketList::NEWPLAYER:
// //
// break;
// case PacketList::DELETEPLAYER:
// //
// break;
case PacketList::MOVEMENT:
Movement(&packet);
break;
}
}
catch(exception& e) {
cerr << "Network Error: " << e.what() << endl;
}
UpdateWorld(double(delta.count()) / Clock::duration::period::den);
//update the world
//TODO Delta::Calculate();
// for (auto it : clientMap) {
// it.second.Update(Delta::GetTime());
// }
//handle output...
//TODO...
SDL_Delay(10);
}
}
void ServerApplication::Quit() {
//close the threads
endQueueThread();
//clean up the services
netUtil->Close();
//delete the services
configUtil = ServiceLocator<ConfigUtility>::Set(nullptr);
netUtil = ServiceLocator<UDPNetworkUtility>::Set(nullptr);
//deinitialize the APIs
netUtil.Close();
SDLNet_Quit();
}
//-------------------------
//Game loop
//network commands
//-------------------------
void ServerApplication::UpdateWorld(double delta) {
for (auto it : players) {
it.second.Update(delta);
void ServerApplication::Ping(PacketData* packet) {
//respond to pings with the server name
if (!packet) {
throw(runtime_error("Ping() received null"));
}
packet->type = PacketList::PONG;
snprintf(packet->pong.metadata,PACKET_STRING_SIZE, "%s",configUtil.CString("servername"));
netUtil.Send(&netUtil.GetInPacket()->address, reinterpret_cast<void*>(packet), sizeof(PacketData));
}
//-------------------------
//Network loop
//-------------------------
int ServerApplication::HandlePacket(Packet p) {
switch(p.meta.type) {
case PacketType::NONE:
//DO NOTHING
return 0;
break;
case PacketType::PING:
//quick pong
p.meta.type = PacketType::PONG;
netUtil->Send(&p.meta.address, &p, sizeof(Packet));
break;
case PacketType::PONG:
//
break;
case PacketType::BROADCAST_REQUEST:
HandleBroadcast(p.broadcastRequest);
break;
// case PacketType::BROADCAST_RESPONSE:
// //
// break;
case PacketType::JOIN_REQUEST:
HandleConnection(p.joinRequest);
break;
// case PacketType::JOIN_RESPONSE:
// //
// break;
case PacketType::DISCONNECT:
HandleDisconnection(p.disconnect);
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) {
//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"));
//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
void ServerApplication::JoinRequest(PacketData* packet) {
if (!packet || clientMap.size() >= maxClients) {
//rejection
return;
}
//create the containers
ClientData client = { uniqueIndex++ };
//add the player
int playerID = uniqueIndex++;
clientMap[playerID].playerID = playerID;
clientMap[playerID].channel = netUtil.Bind(&netUtil.GetInPacket()->address, -1);
clientMap[playerID].handle = packet->joinRequest.handle;
clientMap[playerID].avatar = packet->joinRequest.avatar;
//bind the address
client.channel = netUtil->Bind(&request.meta.address);
//debug
#ifdef DEBUG
cout << "New player:" << endl;
cout << "\tplayerID: " << clientMap[playerID].playerID << endl;
cout << "\tchannel: " << clientMap[playerID].channel << endl;
cout << "\thandle: " << clientMap[playerID].handle << endl;
cout << "\tavatar: " << clientMap[playerID].avatar << endl;
#else
cout << "New player: " << playerID << endl;
#endif
//push this information
clients[client.index] = client;
//join confirm
PacketData p;
p.type = PacketList::JOINCONFIRM;
p.joinConfirm.playerID = clientMap[playerID].playerID;
netUtil.Send(clientMap[playerID].channel, &p, sizeof(PacketData));
//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));
//send it out to the clients
NewClientData(playerID);
//pretty
cout << "New connection: index " << client.index << endl;
cout << "number of clients: " << clients.size() << endl;
#ifdef DEBUG
cout << "current players: " << clientMap.size() << endl;
#endif
}
void ServerApplication::HandleDisconnection(Disconnect& 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);
void ServerApplication::Disconnect(int playerID) {
if (clientMap.find(playerID) == clientMap.end()) {
return;
}
cout << "disconnecting: " << playerID << endl;
//remove the player...
//delete the player from all clients
PacketData p;
p.type = PacketList::DELETEPLAYER;
p.deletePlayer.playerID = playerID;
//pretty
cout << "Lost connection: index " << disconnect.clientIndex << endl;
cout << "number of clients: " << clients.size() << endl;
}
netUtil.SendAll(&p, sizeof(PacketData));
//remove the player from the server
netUtil.Unbind(clientMap[playerID].channel);
clientMap.erase(playerID);
#ifdef DEBUG
cout << "current players: " << clientMap.size() << endl;
#endif
}
void ServerApplication::Movement(PacketData* packet) {
if (!packet) {
throw(runtime_error("Movement() received null"));
}
clientMap[packet->movement.playerID].position = packet->movement.position;
clientMap[packet->movement.playerID].motion = packet->movement.motion;
//simple relay
//TODO: SendClientData(packet->movement.playerID);
for (auto it : clientMap) {
netUtil.Send(it.second.channel, packet, sizeof(PacketData));
}
}
void ServerApplication::NewClientData(int playerID) {
if (clientMap.find(playerID) == clientMap.end()) {
throw(runtime_error("NewClientData() Failed to find the client"));
}
//create the packet to send
PacketData p;
p.type = PacketList::NEWPLAYER;
p.newPlayer.playerID = clientMap[playerID].playerID;
snprintf(p.newPlayer.handle, PACKET_STRING_SIZE, "%s", clientMap[playerID].handle.c_str());
snprintf(p.newPlayer.avatar, PACKET_STRING_SIZE, "%s", clientMap[playerID].avatar.c_str());
p.newPlayer.position = clientMap[playerID].position;
p.newPlayer.motion = clientMap[playerID].motion;
//send the packet
for (auto it : clientMap) {
netUtil.Send(it.second.channel, &p, sizeof(PacketData));
}
}
void ServerApplication::SendClientData(int playerID) {
//relay a client's data
}
void ServerApplication::SynchronizeClient(int playerID) {
//send all server data to a specific client
}
+19 -68
View File
@@ -1,92 +1,43 @@
/* 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 SERVERAPPLICATION_HPP_
#define SERVERAPPLICATION_HPP_
#include "defines.hpp"
#include "packet_type.hpp"
#include "service_locator.hpp"
#include "network_queue.hpp"
#include "client_data.hpp"
#include "config_Utility.hpp"
#include "packet_list.hpp"
#include "config_utility.hpp"
#include "udp_network_utility.hpp"
#include "vector2.hpp"
#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;
}
};
class ServerApplication {
public:
ServerApplication();
~ServerApplication();
ServerApplication() = default;
~ServerApplication() = default;
void Init();
void Proc();
void Quit();
ServerApplication(ServerApplication const&) = delete;
private:
//game loop
void UpdateWorld(double delta);
//network commands
void Ping(PacketData*);
void JoinRequest(PacketData*);
void Disconnect(int playerID);
void Movement(PacketData*);
//network loop
int HandlePacket(Packet p);
void HandleBroadcast(BroadcastRequest&);
void HandleConnection(JoinRequest&);
void HandleDisconnection(Disconnect&);
void NewClientData(int playerID);
void SendClientData(int playerID);
void SynchronizeClient(int playerID);
//services
ConfigUtility* configUtil = nullptr;
UDPNetworkUtility* netUtil = nullptr;
//globals
ConfigUtility configUtil;
UDPNetworkUtility netUtil;
//members
Clock::time_point lastTick = Clock::now();
std::map<int, ClientData> clients;
std::map<int, PlayerData> players;
bool running = false;
std::map<int, ClientData> clientMap;
int maxClients = SDLNET_MAX_UDPCHANNELS;
int uniqueIndex = 0;
};
+26
View File
@@ -0,0 +1,26 @@
#include "udp_network_utility.hpp"
#include "SDL_net/SDL_net.h"
#include <iostream>
#include <string>
using namespace std;
int main(int, char**) {
if (SDLNet_Init()) {
cerr << "Failed to init SDL_net" << endl;
return -1;
}
UDPNetworkUtility netUtil;
netUtil.Open(0, 512);
string s = "Hello world";
netUtil.Send("127.0.0.1", 2000, (void*)s.c_str(), s.length());
netUtil.Close();
SDLNet_Quit();
return 0;
}
-5
View File
@@ -1,5 +0,0 @@
#include "service_locator.hpp"
int FooBar() {
return *ServiceLocator<int>::Get();
}
-6
View File
@@ -1,6 +0,0 @@
#ifndef FOOBAR_HPP_
#define FOOBAR_HPP_
int FooBar();
#endif
-7
View File
@@ -1,7 +0,0 @@
#include "defines.hpp"
int main(int, char**) {
std::string s = itos(5);
return 0;
}
-39
View File
@@ -1,39 +0,0 @@
#config
LIBDIR=../libs
LOCALLIBS=$(LIBDIR)/out/libCodebase.a $(LIBDIR)/out/libCommon.a
LIB=$(LOCALLIBS) -lSDL_net -lwsock32 -liphlpapi -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)/,test)
#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