Compare commits

..

81 Commits

Author SHA1 Message Date
Kayne Ruse 65135b4b86 Codebase update: Added transparency control to Image 2013-07-19 14:06:10 +10:00
Kayne Ruse 51a0974d25 Updated the graphics a bit 2013-07-19 02:02:26 +10:00
Kayne Ruse a23156c425 Added thinner version of the font 2013-07-18 22:53:21 +10:00
Kayne Ruse c03743ed0c Fixed wrong characters being drawn 2013-07-18 18:16:46 +10:00
Kayne Ruse ee3877b906 Pruning unneeded files 2013-07-15 16:36:02 +10:00
Kayne Ruse c4bcced984 Rearranging files 2013-07-15 16:15:46 +10:00
Kayne Ruse 40a40b4e11 Refactored Image 2013-07-15 15:41:41 +10:00
Kayne Ruse 43dadcdbb8 Rearrenged the directory tree
I just _had_ to get rid of that horrible libs/ directory. Now most of the
graphical stuff is in client/, but I'll create more subdirectories so that
they're not getting in the way.
2013-07-15 14:58:12 +10:00
Kayne Ruse 28b491587c This now builds using an external SDL_net 2013-07-14 22:45:47 +10:00
Kayne Ruse 977c2b24fb Codebase update: Made Vector2 a POD 2013-07-11 18:23:51 +10:00
Kayne Ruse 99bbe4be3a Removed the local editor files
I'll be using Sketch to create the maps

git clone https://github.com/Ratstail91/Sketch.git
2013-07-01 18:26:27 +10:00
Kayne Ruse 4dc05f8daf Removed iostream
This was left in by mistake
2013-07-01 18:19:31 +10:00
Kayne Ruse b7205c278a Merge branch 'master' into dev 2013-07-01 18:14:55 +10:00
Kayne Ruse 6bee9b021d Entire project now builds using the local version of SDL_net 2013-07-01 17:57:11 +10:00
Kayne Ruse a49b0eb1fe Changed the timing system to give the machine a rest only when it's OK to 2013-06-26 23:52:31 +10:00
Kayne Ruse 2089105695 Fixed formatting 2013-06-26 17:59:11 +10:00
Kayne Ruse f667f503e7 Simple Multiplayer is working 2013-06-25 00:12:53 +10:00
Kayne Ruse 50bef9736c Deleting players on logout 2013-06-24 23:34:48 +10:00
Kayne Ruse 6d1ba24404 Simplified the packet system 2013-06-24 22:59:06 +10:00
Kayne Ruse ebd8c5e6fc Synchronization works 2013-06-24 21:46:11 +10:00
Kayne Ruse 42f9c5e1df Fixed for loops using the auto keyword 2013-06-24 16:31:38 +10:00
Kayne Ruse 3f2fcdf9e1 Players are being added in the client
The client sends a debug player to the server, with a constant movement to
show that the new client _is_ connecting. The next thing to add is the
sync system, so that the clients know what the server looks like when they
first join.
2013-06-24 16:15:48 +10:00
Kayne Ruse 2235f307e7 Added some multiplayer code to the server 2013-06-24 13:31:19 +10:00
Kayne Ruse 23782ff4e3 Removed maximum number of clients 2013-06-24 12:41:10 +10:00
Kayne Ruse 2a46f82f84 Updated README.md 2013-06-24 12:39:31 +10:00
Kayne Ruse 6a32599a69 Fixed a derp with the time 2013-06-24 12:18:36 +10:00
Kayne Ruse 0ca84a8653 Branch 'dev-map' is stable, merging into 'dev' 2013-06-24 10:45:51 +10:00
Kayne Ruse 66b2d6566c Branch 'dev-char' is stable, merging into 'dev' 2013-06-24 10:43:49 +10:00
Kayne Ruse 56375d64b6 Moved packets into their own namespace 2013-06-24 10:27:43 +10:00
Kayne Ruse 9608761cd5 Moved the entry structs into their own headers 2013-06-24 10:01:52 +10:00
Kayne Ruse c1d03d1cef Changed the name of the editor's main class 2013-06-24 09:26:25 +10:00
Kayne Ruse 09c88c7232 Merge branch 'dev' into dev-map 2013-06-24 09:23:12 +10:00
Kayne Ruse ddb93cfcf1 Changed the name of the client's main class 2013-06-24 09:22:43 +10:00
Kayne Ruse 42787dcb69 Explicitly deleted copy and move constructors 2013-06-24 09:13:27 +10:00
Kayne Ruse fcb17a8116 Merge branch 'dev' into dev-char 2013-06-24 09:02:36 +10:00
Kayne Ruse 2dc21f64fd Merge branch 'dev' into dev-map 2013-06-24 09:01:20 +10:00
Kayne Ruse f049c96df7 Switched from the service locator pattern to singleton pattern 2013-06-24 09:00:50 +10:00
Kayne Ruse d9ffa22b76 Created the editor shell 2013-06-23 16:19:41 +10:00
Kayne Ruse 24654d9e17 Merged the new frame rate system into dev-char 2013-06-23 15:11:24 +10:00
Kayne Ruse 7ad855348f Implemented a simpler frame rate system 2013-06-23 15:05:52 +10:00
Kayne Ruse d833b76856 PlayerCharacter is moving around smoothly 2013-06-23 13:53:55 +10:00
Kayne Ruse 3232925ccd Codebase update 2013-06-22 18:39:56 +10:00
Kayne Ruse e4ffba80aa Fixed incorrect preprocessor guard 2013-06-22 18:22:21 +10:00
Kayne Ruse a4d184ca75 Moved random code out of defines.* 2013-06-21 21:36:48 +10:00
Kayne Ruse 89179626be Improved Vector2 with floats & non-member operators 2013-06-21 15:23:07 +10:00
Kayne Ruse fc381348a5 Updated the game pitch 2013-06-21 14:50:59 +10:00
Kayne Ruse 5e99192fbf Lose focus on a server after a button is released 2013-06-18 19:38:08 +10:00
Kayne Ruse 33adb4b1a5 Put the license header into all source files 2013-06-18 16:40:51 +10:00
Kayne Ruse 33474cc6c0 Smooth connection and disconnection complete
The clients can connect and disconnect from the server with known no
issues. There is no way to shutdown the server yet, but it might be
possible to kick someone else from the server soon.
2013-06-18 16:21:42 +10:00
Kayne Ruse e833129983 Added guards incase of multiple calls 2013-06-18 14:06:57 +10:00
Kayne Ruse fd65fec5f7 The client is registering with the server 2013-06-17 19:53:22 +10:00
Kayne Ruse 69f03cd250 Working on connection systems 2013-06-17 19:04:05 +10:00
Kayne Ruse 27ed91688a Added the meta field to Packet to support Packet's metadata 2013-06-17 18:37:27 +10:00
Kayne Ruse 68ec7323a3 I can't progress until I add the address information to the Packet struct 2013-06-17 17:51:26 +10:00
Kayne Ruse 7b11bf22cb Specified a minimum Packet size for the DEBUG build 2013-06-17 17:14:10 +10:00
Kayne Ruse d83a536f35 Added debug output 2013-06-17 15:57:12 +10:00
Kayne Ruse ea761fb5bb Fixed the bug
running was false when it was checked in networkQueue(), so the thread was
ending early.
2013-06-17 15:49:57 +10:00
Kayne Ruse 685ca94335 This has the odd quirk related to networkQueue() 2013-06-17 15:15:27 +10:00
Kayne Ruse 5b2fd80a61 Fixed the Packet::type bug
In popNetworkPacket(), a second Packet p was being created, which was
destroyed when it went out of scope, and the original Packet p was being
returned.
2013-06-17 11:01:00 +10:00
Kayne Ruse d1aac9ffd8 Added peekNetworkPacket() 2013-06-17 10:12:20 +10:00
Kayne Ruse 3d92fb77b3 Server is multithreaded, but no connection is visible
UDPNetworkUtility and ConfigUtility are now using the ServiceLocator
pattern in the server, and networkQueue() is running in a separate thread
in the server. However, there seems to be a problem somewhere, since the
broadcast request & response are not producing any visible output.
2013-06-17 10:03:12 +10:00
Kayne Ruse 009e7b845b Fixed network error, leaving try block in place for the time being
It seems that the union type Packet didn't initialize Packet::type to
PacketType::NONE using in class initialization. I've fixed this by moving
the initialization of Packet::type to Packet::Packet().

This might actually be a compiler error, I might need to let someone know.
2013-06-17 09:09:04 +10:00
Kayne Ruse 752dcadfa1 Merge branch 'master' into dev 2013-06-17 08:32:02 +10:00
Kayne Ruse 9599d82db3 Added binary files, since git can't find .gitconfig on my brother's PC 2013-06-17 08:31:35 +10:00
Kayne Ruse 7fef2501a3 Glitch with threading 2013-06-17 07:24:16 +10:00
Kayne Ruse 419c9d8765 Moved the common directory into the libs directory 2013-06-16 13:59:11 +10:00
Kayne Ruse a0fa874a29 The server list is being populated from the network 2013-06-13 12:55:26 +10:00
Kayne Ruse 5110ebc1b2 Changed the escape key & quit event's function slightly 2013-06-13 12:31:29 +10:00
Kayne Ruse 843053d307 Implemented the server list box, still messy 2013-06-13 12:26:27 +10:00
Kayne Ruse 2148c1f13e Menu framework in place 2013-06-12 21:56:17 +10:00
Kayne Ruse f3ec4d4d8e Splash screen loads and displays correctly 2013-06-12 19:48:46 +10:00
Kayne Ruse cbd388f4ed Started using ServiceLocator, experimental 2013-06-12 06:35:43 +10:00
Kayne Ruse 37a9e4268b Imported the rsc directory from prototype-1 2013-06-12 05:23:06 +10:00
Kayne Ruse dfe0b4985a Modified build requirements
SDL_net needs to be _installed_ to the computer, rather than simply linked to.
This source distribution should be enough for that.
2013-06-12 04:37:01 +10:00
Kayne Ruse 7ca7f7f015 Added broadcast handling 2013-06-10 18:06:24 +10:00
Kayne Ruse c21a95f3e9 working on the server's skeleton, still slow going 2013-06-10 17:23:26 +10:00
Kayne Ruse 0a48131de4 Added common and test directories 2013-06-09 17:06:32 +10:00
Kayne Ruse 78326a3bbd Added a note about the project's development stage 2013-06-09 14:16:33 +10:00
Kayne Ruse 253e9ec8fc Created server shell 2013-06-08 01:52:19 +10:00
Kayne Ruse a1b248d1d7 Created the client program's framework
There are six scenes here, each of which representing roughly one part of
the final program's backbone.
2013-06-08 01:36:19 +10:00
Kayne Ruse 2757911399 Libraries are building correctly 2013-06-07 04:10:31 +10:00
93 changed files with 1774 additions and 3919 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
#Editor generated files #Editor generated files
*.sln #*.sln
*.vcproj #*.vcproj
*.suo *.suo
*.ncb *.ncb
*.user *.user
+10 -13
View File
@@ -1,20 +1,17 @@
You can find the [latest nightly build here](https://dl.dropboxusercontent.com/u/46669050/Tortuga.rar). _This project is currently in it's early prototype stage. You can see other versions in various branches or tagged as prototype-X._
Tortuga is an open source 2D multiplayer role playing game featuring permadeath (deletion of a character upon death). The emphasis of this game is on multiplayer cooperation, competition, and customization. The game runs on customizable server software that can support up to 150 simultaneous players or more. Tortuga is a 2D multiplayer role playing game set in a large archipelago occupied by warring pirate clans. The emphasis of this game is on multiplayer cooperation, competition, and server customization. The game runs on highly customizable server software that can support up to 150 simultaneous players or more. The player characters are tied to the server where they are created and are susceptible to permadeath: deletion of a character upon death.
This game is inspired by classic 2D RPGs, as well as more modern sandbox MMOs. This project is currently independently created and funded, with the goal of creating a game that will engage user's imagination and inspire a large modding community. ## Dependencies
## External Dependencies * [SDL](http://www.libsdl.org/) - Simple DirectMedia Layer API
* [SDL_net](http://www.libsdl.org/projects/SDL_net/) - SDL's networking extension
* [SDL 1.6](http://www.libsdl.org/) - Simple DirectMedia Layer API ## Instructions
* [SDL_net 1.2](http://www.libsdl.org/projects/SDL_net/) - SDL's networking extension
* [lua 5.2](http://www.lua.org/) - The lua programming language
* [SQLite3](http://www.sqlite.org/) - A lightweight SQL database engine
## Documentation * This project uses C++11, which is available via GNU (or MinGW) 4.7, or Visual Studio 2012. Personally, I'm using MinGW 4.7.2.
* I'm trying to keep this as IDE agnostic as possible, so if you use an IDE, please add it's files to .gitignore.
[Tortuga Game Design Document](https://docs.google.com/document/d/17SjOTdacKKWX0Z-UkaiFnVnjfEeMsc5LRmARtnjh5UI/edit?usp=sharing) * You can read more details on the Tortuga wiki [here](https://github.com/Ratstail91/Tortuga/wiki).
[Tortuga Technical Document](https://docs.google.com/document/d/1ASTfM_1e0yE1cFP-IZey_rHEC6k2kmVY56X4K407sw0/edit?usp=sharing)
## Copyright ## Copyright
@@ -28,4 +25,4 @@ Permission is granted to anyone to use this software for any purpose, including
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution. 3. This notice may not be removed or altered from any source distribution.
@@ -34,7 +34,7 @@ SDL_Surface* BaseScene::screen = nullptr;
//------------------------- //-------------------------
BaseScene::BaseScene() { BaseScene::BaseScene() {
// nextScene = SceneList::CONTINUE;
} }
BaseScene::~BaseScene() { BaseScene::~BaseScene() {
@@ -28,18 +28,18 @@
class BaseScene { class BaseScene {
public: public:
//Public access members /* Public access members */
BaseScene(); BaseScene();
virtual ~BaseScene(); virtual ~BaseScene();
//Program control /* Program control */
static SDL_Surface* SetScreen(int w, int h, int bpp = 0, Uint32 flags = SDL_HWSURFACE|SDL_DOUBLEBUF); static SDL_Surface* SetScreen(int w, int h, int bpp = 0, Uint32 flags = SDL_HWSURFACE|SDL_DOUBLEBUF);
static SDL_Surface* GetScreen(); static SDL_Surface* GetScreen();
SceneList SetNextScene(SceneList sceneIndex); SceneList SetNextScene(SceneList sceneIndex);
SceneList GetNextScene() const; SceneList GetNextScene() const;
//Frame loop /* Frame loop */
virtual void RunFrame(double delta); virtual void RunFrame(double delta);
virtual void RenderFrame(); virtual void RenderFrame();
@@ -50,7 +50,7 @@ protected:
virtual void FrameEnd() {} virtual void FrameEnd() {}
virtual void Render(SDL_Surface* const screen) {} virtual void Render(SDL_Surface* const screen) {}
//Event handlers /* Event handlers */
virtual void QuitEvent() { SetNextScene(SceneList::QUIT); } virtual void QuitEvent() { SetNextScene(SceneList::QUIT); }
virtual void MouseMotion(SDL_MouseMotionEvent const&) {} virtual void MouseMotion(SDL_MouseMotionEvent const&) {}
virtual void MouseButtonDown(SDL_MouseButtonEvent const&) {} virtual void MouseButtonDown(SDL_MouseButtonEvent const&) {}
@@ -68,7 +68,7 @@ protected:
private: private:
static SDL_Surface* screen; static SDL_Surface* screen;
SceneList nextScene = SceneList::CONTINUE; SceneList nextScene;
}; };
#endif #endif
-8
View File
@@ -1,8 +0,0 @@
#ifndef CHANNELS_HPP_
#define CHANNELS_HPP_
enum Channels {
SERVER = 0
};
#endif
+72 -45
View File
@@ -5,7 +5,7 @@
* arising from the use of this software. * arising from the use of this software.
* *
* Permission is granted to anyone to use this software for any purpose, * Permission is granted to anyone to use this software for any purpose,
* including commercial ClientApplications, and to alter it and redistribute it * including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions: * freely, subject to the following restrictions:
* *
* 1. The origin of this software must not be misrepresented; you must not * 1. The origin of this software must not be misrepresented; you must not
@@ -24,23 +24,17 @@
#include <stdexcept> #include <stdexcept>
#include <chrono> #include <chrono>
//-------------------------
//Static declarations
//-------------------------
ClientApplication ClientApplication::instance;
//------------------------- //-------------------------
//Scene headers //Scene headers
//------------------------- //-------------------------
//Add the custom scene headers here //Add the custom scene headers here
#include "splash_screen.hpp"
#include "main_menu.hpp"
#include "options_menu.hpp"
#include "lobby_menu.hpp"
#include "in_world.hpp"
#include "in_combat.hpp" #include "in_combat.hpp"
#include "in_world.hpp"
#include "lobby.hpp"
#include "main_menu.hpp"
#include "option_screen.hpp"
#include "splash_screen.hpp"
//------------------------- //-------------------------
//Public access members //Public access members
@@ -51,33 +45,60 @@ ClientApplication::ClientApplication() {
} }
ClientApplication::~ClientApplication() { ClientApplication::~ClientApplication() {
// UnloadScene();
} }
void ClientApplication::Init() { /* ClientApplication::Init()
//load the prerequisites * This function initializes the entire program. There are a number of things
config.Load("rsc\\config.cfg"); * 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 initialized here.
* The game's screen is created here, based on information loaded from the config file.
* The ConfigUtility's call to Load() also ensures that the "rsc\" folder is in the directory. It's easy to forget it.
*/
//initialize SDL void ClientApplication::Init() {
//load the config file
try {
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)) { if (SDL_Init(SDL_INIT_VIDEO)) {
throw(std::runtime_error("Failed to initialize SDL")); throw(std::runtime_error("Failed to initialize SDL"));
} }
BaseScene::SetScreen(config.Int("screen.w"), config.Int("screen.h"), 0, (config.Bool("screen.f")) ? SDL_HWSURFACE|SDL_DOUBLEBUF : SDL_HWSURFACE);
//initialize SDL_net
if (SDLNet_Init()) { if (SDLNet_Init()) {
throw(std::runtime_error("Failed to initialize SDL_net")); throw(std::runtime_error("Failed to initialize SDL_net"));
} }
network.Open(0, sizeof(NetworkPacket));
//create the screen
Uint32 flags = SDL_HWSURFACE | SDL_DOUBLEBUF;
flags |= configUtil->Bool("screen.f") ? SDL_FULLSCREEN : 0;
BaseScene::SetScreen(
configUtil->Int("screen.w"),
configUtil->Int("screen.h"),
SDL_GetVideoInfo()->vfmt->BitsPerPixel,
flags);
//initiate the remaining singletons
netUtil->Open(0, sizeof(Packet));
} }
void ClientApplication::Proc() { void ClientApplication::Proc() {
LoadScene(SceneList::FIRST); LoadScene(SceneList::FIRST);
//prepare the time system //prepare the time system
typedef std::chrono::steady_clock Clock; typedef std::chrono::high_resolution_clock Clock;
Clock::duration delta(16 * Clock::duration::period::den / std::milli::den); Clock::duration delta(5 * Clock::duration::period::den / std::milli::den);
Clock::time_point simTime = Clock::now(); Clock::time_point simTime = Clock::now();
Clock::time_point realTime; Clock::time_point realTime;
@@ -89,8 +110,10 @@ void ClientApplication::Proc() {
continue; continue;
} }
//update the current time //update the current time & give the computer as much of a break as possible
realTime = Clock::now(); while ((realTime = Clock::now()) < simTime) {
SDL_Delay(1);
}
//simulate game time //simulate game time
while (simTime < realTime) { while (simTime < realTime) {
@@ -101,16 +124,20 @@ void ClientApplication::Proc() {
//draw the game to the screen //draw the game to the screen
activeScene->RenderFrame(); activeScene->RenderFrame();
//give the computer a break
SDL_Delay(10);
} }
UnloadScene(); UnloadScene();
} }
void ClientApplication::Quit() { void ClientApplication::Quit() {
network.Close(); //clean up the singletons
netUtil->Close();
surfaceMgr->FreeAll();
//clean up the scene
UnloadScene();
//deinitialize the APIs
SDLNet_Quit(); SDLNet_Quit();
SDL_Quit(); SDL_Quit();
} }
@@ -124,25 +151,25 @@ void ClientApplication::LoadScene(SceneList sceneIndex) {
switch(sceneIndex) { switch(sceneIndex) {
//add scene creation calls here //add scene creation calls here
case SceneList::FIRST:
case SceneList::SPLASHSCREEN:
activeScene = new SplashScreen(&config);
break;
case SceneList::MAINMENU:
activeScene = new MainMenu(&config);
break;
case SceneList::OPTIONSMENU:
activeScene = new OptionsMenu(&config);
break;
case SceneList::LOBBYMENU:
activeScene = new LobbyMenu(&config, &network, &clientIndex);
break;
case SceneList::INWORLD:
activeScene = new InWorld(&config, &network, &clientIndex);
break;
case SceneList::INCOMBAT: case SceneList::INCOMBAT:
activeScene = new InCombat(); activeScene = new InCombat();
break; break;
case SceneList::INWORLD:
activeScene = new InWorld();
break;
case SceneList::LOBBY:
activeScene = new Lobby();
break;
case SceneList::MAINMENU:
activeScene = new MainMenu();
break;
case SceneList::OPTIONSCREEN:
activeScene = new OptionScreen();
break;
case SceneList::FIRST:
case SceneList::SPLASHSCREEN:
activeScene = new SplashScreen();
break;
default: default:
throw(std::logic_error("Failed to recognize the scene index")); throw(std::logic_error("Failed to recognize the scene index"));
+15 -10
View File
@@ -24,34 +24,39 @@
#include "scene_list.hpp" #include "scene_list.hpp"
#include "base_scene.hpp" #include "base_scene.hpp"
#include "singleton.hpp"
#include "packet.hpp"
#include "information_manager.hpp"
#include "config_utility.hpp" #include "config_utility.hpp"
#include "network_packet.hpp" #include "surface_manager.hpp"
#include "udp_network_utility.hpp" #include "udp_network_utility.hpp"
#include "SDL/SDL.h"
class ClientApplication { class ClientApplication {
private: public:
/* Public access members */
ClientApplication(); ClientApplication();
~ClientApplication(); ~ClientApplication();
static ClientApplication instance;
public:
static ClientApplication* GetInstance() { return &instance; }
void Init(); void Init();
void Proc(); void Proc();
void Quit(); void Quit();
ClientApplication(ClientApplication const&) = delete;
ClientApplication(ClientApplication const&&) = delete;
private: private:
//Private access members /* Private access members */
void LoadScene(SceneList sceneIndex); void LoadScene(SceneList sceneIndex);
void UnloadScene(); void UnloadScene();
BaseScene* activeScene = nullptr; BaseScene* activeScene = nullptr;
ConfigUtility config; ConfigUtility* configUtil = Singleton<ConfigUtility>::Get();
UDPNetworkUtility network; SurfaceManager* surfaceMgr = Singleton<SurfaceManager>::Get();
int clientIndex = -1; //replace with a struct? UDPNetworkUtility* netUtil = Singleton<UDPNetworkUtility>::Get();
InformationManager* infoMgr = Singleton<InformationManager>::Get();
}; };
#endif #endif
@@ -21,16 +21,24 @@
*/ */
#include "in_combat.hpp" #include "in_combat.hpp"
#include <iostream>
using namespace std;
//------------------------- //-------------------------
//Public access members //Public access members
//------------------------- //-------------------------
InCombat::InCombat() { InCombat::InCombat() {
// #ifdef DEBUG
cout << "entering InCombat" << endl;
#endif
} }
InCombat::~InCombat() { InCombat::~InCombat() {
// #ifdef DEBUG
cout << "leaving InCombat" << endl;
#endif
} }
//------------------------- //-------------------------
@@ -26,18 +26,18 @@
class InCombat : public BaseScene { class InCombat : public BaseScene {
public: public:
//Public access members /* Public access members */
InCombat(); InCombat();
~InCombat(); ~InCombat();
protected: protected:
//Frame loop /* Frame loop */
void FrameStart(); void FrameStart();
void Update(double delta); void Update(double delta);
void FrameEnd(); void FrameEnd();
void Render(SDL_Surface* const); void Render(SDL_Surface* const);
//Event handlers /* Event handlers */
void MouseMotion(SDL_MouseMotionEvent const&); void MouseMotion(SDL_MouseMotionEvent const&);
void MouseButtonDown(SDL_MouseButtonEvent const&); void MouseButtonDown(SDL_MouseButtonEvent const&);
void MouseButtonUp(SDL_MouseButtonEvent const&); void MouseButtonUp(SDL_MouseButtonEvent const&);
+326
View File
@@ -0,0 +1,326 @@
/* 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;
//-------------------------
//Quick and dirty
//-------------------------
static std::string itos(int i) {
char buffer[20];
snprintf(buffer, 20, "%d", i);
return std::string(buffer);
}
//-------------------------
//Public access members
//-------------------------
InWorld::InWorld() {
#ifdef DEBUG
cout << "entering InWorld" << endl;
#endif
cout << "Client Index: " << infoMgr->GetClientIndex() << endl;
font.SetSurface(surfaceMgr->Get("font"));
//debugging
Packet p;
p.meta.type = Packet::Type::PLAYER_NEW;
p.meta.clientIndex = infoMgr->GetClientIndex();
snprintf(p.playerInfo.handle, PACKET_STRING_SIZE, "%s", configUtil->CString("handle"));
snprintf(p.playerInfo.avatar, PACKET_STRING_SIZE, "%s", configUtil->CString("avatar"));
p.playerInfo.position.x = 50;
p.playerInfo.position.y = 50;
p.playerInfo.motion.x = 0;
p.playerInfo.motion.y = 0;
netUtil->Send(GAME_CHANNEL, &p, sizeof(Packet));
//request a sync
p.meta.type = Packet::Type::SYNCHRONIZE;
p.meta.clientIndex = infoMgr->GetClientIndex();
netUtil->Send(GAME_CHANNEL, &p, sizeof(Packet));
}
InWorld::~InWorld() {
#ifdef DEBUG
cout << "leaving InWorld" << endl;
#endif
}
//-------------------------
//Frame loop
//-------------------------
void InWorld::FrameStart() {
//
}
void InWorld::Update(double delta) {
while(HandlePacket(popNetworkPacket()));
for (auto& it : playerCharacters) {
it.second.Update(delta);
}
}
void InWorld::FrameEnd() {
//
}
void InWorld::Render(SDL_Surface* const screen) {
clockFrameRate();
for (auto& it : playerCharacters) {
it.second.DrawTo(screen);
}
//since we're using this twice, make a tmp var
string fps = itos(getFrameRate());
font.DrawStringTo(fps, screen, screen->w - fps.size() * font.GetCharW(), 0);
}
//-------------------------
//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) {
//general
switch(key.keysym.sym) {
case SDLK_ESCAPE:
ExitGame();
break;
}
//player movement
if (infoMgr->GetPlayerIndex() == -1) {
return;
}
switch(key.keysym.sym) {
case SDLK_w:
playerCharacters[infoMgr->GetPlayerIndex()].MoveDirection(CardinalDirection::NORTH);
SendState();
break;
case SDLK_s:
playerCharacters[infoMgr->GetPlayerIndex()].MoveDirection(CardinalDirection::SOUTH);
SendState();
break;
case SDLK_a:
playerCharacters[infoMgr->GetPlayerIndex()].MoveDirection(CardinalDirection::WEST);
SendState();
break;
case SDLK_d:
playerCharacters[infoMgr->GetPlayerIndex()].MoveDirection(CardinalDirection::EAST);
SendState();
break;
}
}
void InWorld::KeyUp(SDL_KeyboardEvent const& key) {
//player movement reversed
switch(key.keysym.sym) {
case SDLK_w:
playerCharacters[infoMgr->GetPlayerIndex()].MoveDirection(CardinalDirection::SOUTH);
SendState();
break;
case SDLK_s:
playerCharacters[infoMgr->GetPlayerIndex()].MoveDirection(CardinalDirection::NORTH);
SendState();
break;
case SDLK_a:
playerCharacters[infoMgr->GetPlayerIndex()].MoveDirection(CardinalDirection::EAST);
SendState();
break;
case SDLK_d:
playerCharacters[infoMgr->GetPlayerIndex()].MoveDirection(CardinalDirection::WEST);
SendState();
break;
}
}
//-------------------------
//Utilities
//-------------------------
int InWorld::HandlePacket(Packet p) {
switch(p.meta.type) {
case Packet::Type::NONE:
//DO NOTHING
return 0;
break;
case Packet::Type::PING:
//quick pong
p.meta.type = Packet::Type::PONG;
p.meta.clientIndex = infoMgr->GetClientIndex();
netUtil->Send(&p.meta.address, &p, sizeof(Packet));
break;
case Packet::Type::PONG:
//
break;
// case Packet::Type::BROADCAST_REQUEST:
// //
// break;
// case Packet::Type::BROADCAST_RESPONSE:
// //
// break;
// case Packet::Type::JOIN_REQUEST:
// //
// break;
// case Packet::Type::JOIN_RESPONSE:
// //
// break;
case Packet::Type::DISCONNECT:
HandleDisconnection(p);
break;
// case Packet::Type::SYNCHRONIZE:
// //
// break;
case Packet::Type::PLAYER_NEW:
AddPlayer(p);
break;
case Packet::Type::PLAYER_DELETE:
RemovePlayer(p);
break;
case Packet::Type::PLAYER_UPDATE:
UpdatePlayer(p);
break;
default:
throw(runtime_error("Failed to recognize the packet type: " + itos(int(p.meta.type))));
}
return 1;
}
void InWorld::Disconnect() {
Packet p;
//delete the player
p.meta.type = Packet::Type::PLAYER_DELETE;
p.meta.clientIndex = infoMgr->GetClientIndex();
p.playerInfo.index = infoMgr->GetPlayerIndex();
netUtil->Send(GAME_CHANNEL, &p, sizeof(Packet));
//disconnect
p.meta.type = Packet::Type::DISCONNECT;
p.meta.clientIndex = infoMgr->GetClientIndex();
netUtil->Send(GAME_CHANNEL, &p, sizeof(Packet));
netUtil->Unbind(GAME_CHANNEL);
//reset the client
infoMgr->ResetClientIndex();
infoMgr->ResetPlayerIndex();
}
void InWorld::ExitGame() {
Disconnect();
SetNextScene(SceneList::MAINMENU);
endQueueThread();
cout << "The game session has ended" << endl;
}
void InWorld::HandleDisconnection(Packet& disconnect) {
Disconnect();
SetNextScene(SceneList::MAINMENU);
endQueueThread();
cout << "You have been disconnected" << endl;
}
void InWorld::AddPlayer(Packet& p) {
if (playerCharacters.find(p.playerInfo.index) != playerCharacters.end()) {
throw(runtime_error("Duplicate players detected"));
}
//position
playerCharacters[p.playerInfo.index].SetPosition(p.playerInfo.position);
playerCharacters[p.playerInfo.index].SetMotion(p.playerInfo.motion);
//sprite
playerCharacters[p.playerInfo.index].GetSprite()->SetSurface(surfaceMgr->Get(p.playerInfo.avatar), 32, 48);
playerCharacters[p.playerInfo.index].FaceDirection();
//is it this player?
if (p.meta.clientIndex == infoMgr->GetClientIndex()) {
infoMgr->SetPlayerIndex(p.playerInfo.index);
}
//debugging
cout << "New player, index " << p.playerInfo.index << endl;
}
void InWorld::RemovePlayer(Packet& p) {
if (playerCharacters.find(p.playerInfo.index) == playerCharacters.end()) {
throw(runtime_error("Player to delete not found"));
}
playerCharacters.erase(p.playerInfo.index);
}
void InWorld::UpdatePlayer(Packet& p) {
if (playerCharacters.find(p.playerInfo.index) == playerCharacters.end()) {
AddPlayer(p);
return;
}
playerCharacters[p.playerInfo.index].SetPosition(p.playerInfo.position);
playerCharacters[p.playerInfo.index].SetMotion(p.playerInfo.motion);
playerCharacters[p.playerInfo.index].FaceDirection();
}
void InWorld::SendState() {
//send the state of this player's character
if (infoMgr->GetPlayerIndex() == -1) {
return;
}
Packet p;
p.meta.type = Packet::Type::PLAYER_UPDATE;
p.meta.clientIndex = infoMgr->GetClientIndex();
p.playerInfo.index = infoMgr->GetPlayerIndex();
p.playerInfo.position = playerCharacters[infoMgr->GetPlayerIndex()].GetPosition();
p.playerInfo.motion = playerCharacters[infoMgr->GetPlayerIndex()].GetMotion();
netUtil->Send(GAME_CHANNEL, &p, sizeof(Packet));
}
@@ -24,20 +24,26 @@
#include "base_scene.hpp" #include "base_scene.hpp"
#include "config_utility.hpp" #include "defines.hpp"
#include "udp_network_utility.hpp" #include "singleton.hpp"
#include "network_packet.hpp" #include "packet.hpp"
#include "image.hpp" #include "network_queue.hpp"
#include "raster_font.hpp" #include "information_manager.hpp"
#include "button.hpp"
#include "player_character.hpp" #include "player_character.hpp"
#include "config_utility.hpp"
#include "surface_manager.hpp"
#include "udp_network_utility.hpp"
#include "button.hpp"
#include "raster_font.hpp"
#include "frame_rate.hpp"
#include <map> #include <map>
class InWorld : public BaseScene { class InWorld : public BaseScene {
public: public:
//Public access members //Public access members
InWorld(ConfigUtility* const, UDPNetworkUtility* const, int* const); InWorld();
~InWorld(); ~InWorld();
protected: protected:
@@ -55,29 +61,28 @@ protected:
void KeyDown(SDL_KeyboardEvent const&); void KeyDown(SDL_KeyboardEvent const&);
void KeyUp(SDL_KeyboardEvent const&); void KeyUp(SDL_KeyboardEvent const&);
void HandlePacket(NetworkPacket); //Utilities
void HandleDisconnect(NetworkPacket); int HandlePacket(Packet);
void HandlePlayerNew(NetworkPacket); void Disconnect();
void HandlePlayerDelete(NetworkPacket); void ExitGame();
void HandlePlayerUpdate(NetworkPacket);
void HandleDisconnection(Packet&);
void AddPlayer(Packet&);
void RemovePlayer(Packet&);
void UpdatePlayer(Packet&);
void SendState(); void SendState();
void RequestDisconnect();
void RequestShutDown();
//global //services
ConfigUtility& config; ConfigUtility* configUtil = Singleton<ConfigUtility>::Get();
UDPNetworkUtility& network; SurfaceManager* surfaceMgr = Singleton<SurfaceManager>::Get();
int& clientIndex; UDPNetworkUtility* netUtil = Singleton<UDPNetworkUtility>::Get();
InformationManager* infoMgr = Singleton<InformationManager>::Get();
//members //members
Image image;
RasterFont font; RasterFont font;
Button disconnectButton;
Button shutDownButton;
std::map<int, PlayerCharacter> playerCharacters; std::map<int, PlayerCharacter> playerCharacters;
PlayerCharacter* localCharacter = nullptr;
int playerIndex = -1;
}; };
#endif #endif
+40
View File
@@ -0,0 +1,40 @@
/* 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; }
//one player at a time
int SetPlayerIndex(int i) { return playerIndex = i; }
int GetPlayerIndex() { return playerIndex; }
void ResetPlayerIndex() { playerIndex = -1; }
private:
int clientIndex = -1;
int playerIndex = -1;
};
#endif
+244
View File
@@ -0,0 +1,244 @@
/* 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 <iostream>
using namespace std;
//-------------------------
//Quick and dirty
//-------------------------
static std::string itos(int i) {
char buffer[20];
snprintf(buffer, 20, "%d", i);
return std::string(buffer);
}
//-------------------------
//Public access members
//-------------------------
Lobby::Lobby() {
#ifdef DEBUG
cout << "entering Lobby" << endl;
#endif
refreshButton.Setup(50, 50, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Refresh");
joinButton.Setup(50, 50 + surfaceMgr->Get("button")->h/3, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Join");
backButton.Setup(50, 50 + surfaceMgr->Get("button")->h/3 * 2, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Back");
font.SetSurface(surfaceMgr->Get("font"));
listBox.x = 280;
listBox.y = 50;
listBox.w = GetScreen()->w - listBox.x - 50;
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();
}
Lobby::~Lobby() {
#ifdef DEBUG
cout << "leaving Lobby" << endl;
#endif
}
//-------------------------
//Frame loop
//-------------------------
void Lobby::FrameStart() {
//
}
void Lobby::Update(double delta) {
while(HandlePacket(popNetworkPacket()));
}
void Lobby::FrameEnd() {
//
}
void Lobby::Render(SDL_Surface* const screen) {
refreshButton.DrawTo(screen);
joinButton.DrawTo(screen);
backButton.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));
}
font.DrawStringTo(serverList[i].name, screen, listBox.x, listBox.y + i * font.GetCharH());
}
}
//-------------------------
//Event handlers
//-------------------------
void Lobby::MouseMotion(SDL_MouseMotionEvent const& motion) {
refreshButton.MouseMotion(motion);
joinButton.MouseMotion(motion);
backButton.MouseMotion(motion);
}
void Lobby::MouseButtonDown(SDL_MouseButtonEvent const& button) {
refreshButton.MouseButtonDown(button);
joinButton.MouseButtonDown(button);
backButton.MouseButtonDown(button);
}
void Lobby::MouseButtonUp(SDL_MouseButtonEvent const& button) {
if (refreshButton.MouseButtonUp(button) == Button::State::HOVER) {
BroadcastNetwork();
selectedServer = nullptr;
}
else if (joinButton.MouseButtonUp(button) == Button::State::HOVER) {
if (selectedServer) {
ConnectToServer(selectedServer);
selectedServer = nullptr;
}
}
else if (backButton.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];
}
else {
//lose focus on a server
selectedServer = nullptr;
}
}
void Lobby::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE:
SetNextScene(SceneList::MAINMENU);
break;
}
}
void Lobby::KeyUp(SDL_KeyboardEvent const& key) {
//
}
//-------------------------
//Utilities
//-------------------------
int Lobby::HandlePacket(Packet p) {
switch(p.meta.type) {
case Packet::Type::NONE:
//DO NOTHING
return 0;
break;
case Packet::Type::PING:
//quick pong
p.meta.type = Packet::Type::PONG;
netUtil->Send(&p.meta.address, &p, sizeof(Packet));
break;
case Packet::Type::PONG:
//
break;
// case Packet::Type::BROADCAST_REQUEST:
// //
// break;
case Packet::Type::BROADCAST_RESPONSE:
PushServer(p);
break;
// case Packet::Type::JOIN_REQUEST:
// //
// break;
case Packet::Type::JOIN_RESPONSE:
BeginGame(p);
break;
// case Packet::Type::DISCONNECT:
// //
// break;
// case Packet::Type::SYNCHRONIZE:
// //
// break;
// case Packet::Type::PLAYER_NEW:
// //
// break;
// case Packet::Type::PLAYER_DELETE:
// //
// break;
// case Packet::Type::PLAYER_UPDATE:
// //
// break;
default:
throw(runtime_error("Failed to recognize the packet type: " + itos(int(p.meta.type))));
}
return 1;
}
void Lobby::BroadcastNetwork() {
Packet p;
p.meta.type = Packet::Type::BROADCAST_REQUEST;
netUtil->Send("255.255.255.255", configUtil->Int("server.port"), &p, sizeof(Packet));
serverList.clear();
}
void Lobby::PushServer(Packet& bcast) {
ServerEntry entry;
entry.name = bcast.serverInfo.name;
entry.address = bcast.meta.address;
serverList.push_back(entry);
}
void Lobby::ConnectToServer(ServerEntry* server) {
//_attempt_ to connect to a server
if (!server) {
throw(runtime_error("No server received"));
}
Packet p;
p.meta.type = Packet::Type::JOIN_REQUEST;
netUtil->Send(&server->address, reinterpret_cast<void*>(&p), sizeof(Packet));
}
void Lobby::BeginGame(Packet& response) {
//should be downloading the resources here as well
infoMgr->SetClientIndex(response.meta.clientIndex);
netUtil->Bind(&response.meta.address, GAME_CHANNEL);
SetNextScene(SceneList::INWORLD);
}
@@ -19,26 +19,38 @@
* 3. This notice may not be removed or altered from any source * 3. This notice may not be removed or altered from any source
* distribution. * distribution.
*/ */
#ifndef LOBBYMENU_HPP_ #ifndef LOBBY_HPP_
#define LOBBYMENU_HPP_ #define LOBBY_HPP_
#include "base_scene.hpp" #include "base_scene.hpp"
#include "image.hpp" #include "defines.hpp"
#include "raster_font.hpp" #include "singleton.hpp"
#include "button.hpp"
#include "packet.hpp"
#include "network_queue.hpp"
#include "information_manager.hpp"
#include "config_utility.hpp" #include "config_utility.hpp"
#include "surface_manager.hpp"
#include "udp_network_utility.hpp" #include "udp_network_utility.hpp"
#include "network_packet.hpp" #include "button.hpp"
#include "raster_font.hpp"
#include <vector> #include <vector>
#include <string>
class LobbyMenu : public BaseScene { struct ServerEntry {
std::string name;
IPaddress address;
//TODO: player count
};
class Lobby : public BaseScene {
public: public:
//Public access members //Public access members
LobbyMenu(ConfigUtility* const, UDPNetworkUtility* const, int* const); Lobby();
~LobbyMenu(); ~Lobby();
protected: protected:
//Frame loop //Frame loop
@@ -54,32 +66,28 @@ protected:
void KeyDown(SDL_KeyboardEvent const&); void KeyDown(SDL_KeyboardEvent const&);
void KeyUp(SDL_KeyboardEvent const&); void KeyUp(SDL_KeyboardEvent const&);
void HandlePacket(NetworkPacket); //utilities
int HandlePacket(Packet);
void BroadcastNetwork();
void PushServer(Packet&);
void ConnectToServer(ServerEntry*);
void BeginGame(Packet&);
//global //services
ConfigUtility& config; ConfigUtility* configUtil = Singleton<ConfigUtility>::Get();
UDPNetworkUtility& network; SurfaceManager* surfaceMgr = Singleton<SurfaceManager>::Get();
int& clientIndex; UDPNetworkUtility* netUtil = Singleton<UDPNetworkUtility>::Get();
InformationManager* infoMgr = Singleton<InformationManager>::Get();
//members //members
Image image; Button refreshButton;
Button joinButton;
Button backButton;
RasterFont font; RasterFont font;
Button search;
Button join;
Button back;
//server list
struct ServerInformation {
std::string name;
IPaddress address;
};
std::vector<ServerInformation> serverInfo;
//a terrible hack, forgive me
//I'd love a proper gui system for this
SDL_Rect listBox; SDL_Rect listBox;
ServerInformation* selection = nullptr; std::vector<ServerEntry> serverList;
ServerEntry* selectedServer = nullptr;
}; };
#endif #endif
+10 -5
View File
@@ -27,16 +27,21 @@
using namespace std; using namespace std;
int main(int, char**) { int main(int, char**) {
cout << "Beginning client" << endl; #ifdef DEBUG
cout << "Beginning program" << endl;
#endif
try { try {
ClientApplication::GetInstance()->Init(); ClientApplication app;
ClientApplication::GetInstance()->Proc(); app.Init();
ClientApplication::GetInstance()->Quit(); app.Proc();
app.Quit();
} }
catch(exception& e) { catch(exception& e) {
cerr << "Fatal exception thrown: " << e.what() << endl; cerr << "Fatal error: " << e.what() << endl;
return 1; return 1;
} }
#ifdef DEBUG
cout << "Clean exit" << endl; cout << "Clean exit" << endl;
#endif
return 0; return 0;
} }
@@ -21,42 +21,27 @@
*/ */
#include "main_menu.hpp" #include "main_menu.hpp"
#include <iostream>
using namespace std;
//------------------------- //-------------------------
//Public access members //Public access members
//------------------------- //-------------------------
MainMenu::MainMenu(ConfigUtility* const argConfig): MainMenu::MainMenu() {
config(*argConfig) #ifdef DEBUG
{ cout << "entering MainMenu" << endl;
//setup the utility objects #endif
image.LoadSurface(config["dir.interface"] + "button_menu.bmp"); startButton.Setup(50, 50, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Start");
image.SetClipH(image.GetClipH()/3); optionsButton.Setup(50, 50 + surfaceMgr->Get("button")->h/3, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Options");
font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp"); quitButton.Setup(50, 50 + surfaceMgr->Get("button")->h/3 * 2, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Quit");
//pass the utility objects
startButton.SetImage(&image);
startButton.SetFont(&font);
optionsButton.SetImage(&image);
optionsButton.SetFont(&font);
quitButton.SetImage(&image);
quitButton.SetFont(&font);
//set the button positions
startButton.SetX(50);
startButton.SetY(50 + image.GetClipH() * 0);
optionsButton.SetX(50);
optionsButton.SetY(50 + image.GetClipH() * 1);
quitButton.SetX(50);
quitButton.SetY(50 + image.GetClipH() * 2);
//set the button texts
startButton.SetText("Start");
optionsButton.SetText("Options");
quitButton.SetText("Quit");
} }
MainMenu::~MainMenu() { MainMenu::~MainMenu() {
// #ifdef DEBUG
cout << "leaving MainMenu" << endl;
#endif
} }
//------------------------- //-------------------------
@@ -99,10 +84,10 @@ void MainMenu::MouseButtonDown(SDL_MouseButtonEvent const& button) {
void MainMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) { void MainMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) {
if (startButton.MouseButtonUp(button) == Button::State::HOVER) { if (startButton.MouseButtonUp(button) == Button::State::HOVER) {
SetNextScene(SceneList::LOBBYMENU); SetNextScene(SceneList::LOBBY);
} }
if (optionsButton.MouseButtonUp(button) == Button::State::HOVER) { if (optionsButton.MouseButtonUp(button) == Button::State::HOVER) {
SetNextScene(SceneList::OPTIONSMENU); SetNextScene(SceneList::OPTIONSCREEN);
} }
if (quitButton.MouseButtonUp(button) == Button::State::HOVER) { if (quitButton.MouseButtonUp(button) == Button::State::HOVER) {
QuitEvent(); QuitEvent();
@@ -113,10 +98,6 @@ void MainMenu::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) { switch(key.keysym.sym) {
case SDLK_ESCAPE: case SDLK_ESCAPE:
QuitEvent(); QuitEvent();
break; break;
} }
} }
void MainMenu::KeyUp(SDL_KeyboardEvent const& key) {
//
}
@@ -23,38 +23,32 @@
#define MAINMENU_HPP_ #define MAINMENU_HPP_
#include "base_scene.hpp" #include "base_scene.hpp"
#include "singleton.hpp"
#include "config_utility.hpp" #include "surface_manager.hpp"
#include "image.hpp"
#include "raster_font.hpp"
#include "button.hpp" #include "button.hpp"
class MainMenu : public BaseScene { class MainMenu : public BaseScene {
public: public:
//Public access members /* Public access members */
MainMenu(ConfigUtility* const); MainMenu();
~MainMenu(); ~MainMenu();
protected: protected:
//Frame loop /* Frame loop */
void FrameStart(); void FrameStart();
void Update(double delta); void Update(double delta);
void FrameEnd(); void FrameEnd();
void Render(SDL_Surface* const); void Render(SDL_Surface* const);
//Event handlers /* Event handlers */
void MouseMotion(SDL_MouseMotionEvent const&); void MouseMotion(SDL_MouseMotionEvent const&);
void MouseButtonDown(SDL_MouseButtonEvent const&); void MouseButtonDown(SDL_MouseButtonEvent const&);
void MouseButtonUp(SDL_MouseButtonEvent const&); void MouseButtonUp(SDL_MouseButtonEvent const&);
void KeyDown(SDL_KeyboardEvent const&); void KeyDown(SDL_KeyboardEvent const&);
void KeyUp(SDL_KeyboardEvent const&);
//globals SurfaceManager* surfaceMgr = Singleton<SurfaceManager>::Get();
ConfigUtility& config;
//members
Image image;
RasterFont font;
Button startButton; Button startButton;
Button optionsButton; Button optionsButton;
Button quitButton; Button quitButton;
+6 -12
View File
@@ -1,17 +1,15 @@
#config #config
INCLUDES+=. scenes ../common ../common/graphics ../common/map ../common/network ../common/ui LOCALLIBS=../lib/libCommon.a
LIBS+=libclient.a ../libcommon.a -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL -llua -lsqlite3 LIB=$(LOCALLIBS) -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL
INCLUDES=../common
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES)) CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
#source #source
CXXSRC=$(wildcard *.cpp) SRC=$(wildcard *.cpp)
CSRC=$(wildcard *.c)
#objects #objects
OBJDIR=obj OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o)) OBJ=$(addprefix $(OBJDIR)/,$(SRC:.cpp=.o))
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
#output #output
OUTDIR=../out OUTDIR=../out
@@ -19,8 +17,7 @@ OUT=$(addprefix $(OUTDIR)/,client)
#targets #targets
all: $(OBJ) $(OUT) all: $(OBJ) $(OUT)
$(MAKE) -C scenes $(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIB)
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS)
$(OBJ): | $(OBJDIR) $(OBJ): | $(OBJDIR)
@@ -35,9 +32,6 @@ $(OUTDIR):
$(OBJDIR)/%.o: %.cpp $(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $< $(CXX) $(CXXFLAGS) -c -o $@ $<
$(OBJDIR)/%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean: clean:
$(RM) *.o *.a *.exe $(RM) *.o *.a *.exe
@@ -19,84 +19,59 @@
* 3. This notice may not be removed or altered from any source * 3. This notice may not be removed or altered from any source
* distribution. * distribution.
*/ */
#include "options_menu.hpp" #include "option_screen.hpp"
#include <iostream>
using namespace std;
//------------------------- //-------------------------
//Public access members //Public access members
//------------------------- //-------------------------
OptionsMenu::OptionsMenu(ConfigUtility* const argConfig): OptionScreen::OptionScreen() {
config(*argConfig) #ifdef DEBUG
{ cout << "entering OptionScreen" << endl;
//setup the utility objects #endif
image.LoadSurface(config["dir.interface"] + "button_menu.bmp"); backButton.Setup(50, 50, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Back");
image.SetClipH(image.GetClipH()/3);
font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp");
//pass the utility objects
backButton.SetImage(&image);
backButton.SetFont(&font);
//set the button positions
backButton.SetX(50);
backButton.SetY(50 + image.GetClipH() * 0);
//set the button texts
backButton.SetText("Back");
} }
OptionsMenu::~OptionsMenu() { OptionScreen::~OptionScreen() {
// #ifdef DEBUG
cout << "leaving OptionScreen" << endl;
#endif
} }
//------------------------- //-------------------------
//Frame loop //Frame loop
//------------------------- //-------------------------
void OptionsMenu::FrameStart() { void OptionScreen::Render(SDL_Surface* const screen) {
//
}
void OptionsMenu::Update(double delta) {
//
}
void OptionsMenu::FrameEnd() {
//
}
void OptionsMenu::Render(SDL_Surface* const screen) {
backButton.DrawTo(screen); backButton.DrawTo(screen);
font.DrawStringTo("Oh, were you looking for the options screen?", screen, 50, 30);
} }
//------------------------- //-------------------------
//Event handlers //Event handlers
//------------------------- //-------------------------
void OptionsMenu::MouseMotion(SDL_MouseMotionEvent const& motion) { void OptionScreen::MouseMotion(SDL_MouseMotionEvent const& motion) {
backButton.MouseMotion(motion); backButton.MouseMotion(motion);
} }
void OptionsMenu::MouseButtonDown(SDL_MouseButtonEvent const& button) { void OptionScreen::MouseButtonDown(SDL_MouseButtonEvent const& button) {
backButton.MouseButtonDown(button); backButton.MouseButtonDown(button);
} }
void OptionsMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) { void OptionScreen::MouseButtonUp(SDL_MouseButtonEvent const& button) {
if (backButton.MouseButtonUp(button) == Button::State::HOVER) { if (backButton.MouseButtonUp(button) == Button::State::HOVER) {
SetNextScene(SceneList::MAINMENU); SetNextScene(SceneList::MAINMENU);
} }
} }
void OptionsMenu::KeyDown(SDL_KeyboardEvent const& key) { void OptionScreen::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) { switch(key.keysym.sym) {
case SDLK_ESCAPE: case SDLK_ESCAPE:
SetNextScene(SceneList::MAINMENU); SetNextScene(SceneList::MAINMENU);
break; break;
} }
} }
void OptionsMenu::KeyUp(SDL_KeyboardEvent const& key) {
//
}
@@ -19,42 +19,32 @@
* 3. This notice may not be removed or altered from any source * 3. This notice may not be removed or altered from any source
* distribution. * distribution.
*/ */
#ifndef OPTIONSMENU_HPP_ #ifndef OPTIONSCREEN_HPP_
#define OPTIONSMENU_HPP_ #define OPTIONSCREEN_HPP_
#include "base_scene.hpp" #include "base_scene.hpp"
#include "singleton.hpp"
#include "config_utility.hpp" #include "surface_manager.hpp"
#include "image.hpp"
#include "raster_font.hpp"
#include "button.hpp" #include "button.hpp"
class OptionsMenu : public BaseScene { class OptionScreen : public BaseScene {
public: public:
//Public access members /* Public access members */
OptionsMenu(ConfigUtility* const); OptionScreen();
~OptionsMenu(); ~OptionScreen();
protected: protected:
//Frame loop /* Frame loop */
void FrameStart();
void Update(double delta);
void FrameEnd();
void Render(SDL_Surface* const); void Render(SDL_Surface* const);
//Event handlers /* Event handlers */
void MouseMotion(SDL_MouseMotionEvent const&); void MouseMotion(SDL_MouseMotionEvent const&);
void MouseButtonDown(SDL_MouseButtonEvent const&); void MouseButtonDown(SDL_MouseButtonEvent const&);
void MouseButtonUp(SDL_MouseButtonEvent const&); void MouseButtonUp(SDL_MouseButtonEvent const&);
void KeyDown(SDL_KeyboardEvent const&); void KeyDown(SDL_KeyboardEvent const&);
void KeyUp(SDL_KeyboardEvent const&);
//globals SurfaceManager* surfaceMgr = Singleton<SurfaceManager>::Get();
ConfigUtility& config;
//members
Image image;
RasterFont font;
Button backButton; Button backButton;
}; };
+33 -36
View File
@@ -21,10 +21,8 @@
*/ */
#include "player_character.hpp" #include "player_character.hpp"
#define WALKING_SPEED 140
void PlayerCharacter::Update(double delta) { void PlayerCharacter::Update(double delta) {
if (diagonal) { if (limitSpeed) {
constexpr double d = 1.0/sqrt(2); constexpr double d = 1.0/sqrt(2);
position += motion * delta * d; position += motion * delta * d;
} }
@@ -34,84 +32,83 @@ void PlayerCharacter::Update(double delta) {
sprite.Update(delta); sprite.Update(delta);
} }
void PlayerCharacter::AdjustDirection(Direction direction) { void PlayerCharacter::MoveDirection(CardinalDirection cd) {
//shift the movement in this direction //shift the movement in this direction
switch(direction) { switch(cd) {
case Direction::NORTH: case CardinalDirection::NORTH:
if (motion.y >= 0) { if (motion.y >= 0) {
motion.y -= WALKING_SPEED; motion.y -= WALKING_SPEED;
} }
break; break;
case Direction::SOUTH: case CardinalDirection::SOUTH:
if (motion.y <= 0) { if (motion.y <= 0) {
motion.y += WALKING_SPEED; motion.y += WALKING_SPEED;
} }
break; break;
case Direction::WEST: case CardinalDirection::WEST:
if (motion.x >= 0) { if (motion.x >= 0) {
motion.x -= WALKING_SPEED; motion.x -= WALKING_SPEED;
} }
break; break;
case Direction::EAST: case CardinalDirection::EAST:
if (motion.x <= 0) { if (motion.x <= 0) {
motion.x += WALKING_SPEED; motion.x += WALKING_SPEED;
} }
break; break;
} }
//face the correct direction //face the correct direction
ResetDirection(); FaceDirection();
} }
void PlayerCharacter::FaceDirection(Direction direction) { void PlayerCharacter::FaceDirection(CardinalDirection cd) {
//this function depends on the format of the sprite sheets switch(cd) {
switch(direction) { case CardinalDirection::NORTH:
case Direction::NORTH: sprite.SetCurrentStrip(1);
sprite.SetYIndex(1);
break; break;
case Direction::SOUTH: case CardinalDirection::SOUTH:
sprite.SetYIndex(0); sprite.SetCurrentStrip(0);
break; break;
case Direction::WEST: case CardinalDirection::WEST:
sprite.SetYIndex(2); sprite.SetCurrentStrip(2);
break; break;
case Direction::EAST: case CardinalDirection::EAST:
sprite.SetYIndex(3); sprite.SetCurrentStrip(3);
break; break;
} }
} }
void PlayerCharacter::ResetDirection() { void PlayerCharacter::FaceDirection() {
//base the direction on the character's movement //base the direction on the character's movement
if (motion.y < 0) {
FaceDirection(CardinalDirection::NORTH);
}
if (motion.y > 0) { if (motion.y > 0) {
FaceDirection(Direction::SOUTH); FaceDirection(CardinalDirection::SOUTH);
} }
else if (motion.y < 0) { if (motion.x < 0) {
FaceDirection(Direction::NORTH); FaceDirection(CardinalDirection::WEST);
} }
else if (motion.x > 0) { if (motion.x > 0) {
FaceDirection(Direction::EAST); FaceDirection(CardinalDirection::EAST);
} }
else if (motion.x < 0) { CheckSpeed();
FaceDirection(Direction::WEST);
}
ResetSpeed();
} }
void PlayerCharacter::ResetSpeed() { void PlayerCharacter::CheckSpeed() {
//diagonal //diagonal
if (motion.x != 0 && motion.y != 0) { if (motion.x != 0 && motion.y != 0) {
sprite.SetDelay(0.1); sprite.SetDelay(0.1);
diagonal = true; limitSpeed = true;
} }
//cardinal //cardinal
else if (motion != 0) { else if (motion != 0) {
sprite.SetDelay(0.1); sprite.SetDelay(0.1);
diagonal = false; limitSpeed = false;
} }
//not moving //not moving
else { else {
sprite.SetDelay(0); sprite.SetDelay(0);
sprite.SetXIndex(0); sprite.SetCurrentFrame(0);
diagonal = false; limitSpeed = false;
} }
} }
+9 -12
View File
@@ -24,25 +24,20 @@
#include "vector2.hpp" #include "vector2.hpp"
#include "sprite_sheet.hpp" #include "sprite_sheet.hpp"
#include "defines.hpp"
class PlayerCharacter { class PlayerCharacter {
public: public:
enum class Direction {
NORTH, SOUTH, EAST, WEST
};
PlayerCharacter() = default; PlayerCharacter() = default;
~PlayerCharacter() = default; ~PlayerCharacter() = default;
void Update(double delta); void Update(double delta);
void DrawTo(SDL_Surface* const dest) { sprite.DrawTo(dest, position.x, position.y); } void MoveDirection(CardinalDirection);
void FaceDirection(CardinalDirection);
void FaceDirection();
//clunky code results in smooth movement and controls void DrawTo(SDL_Surface* const dest) { sprite.DrawTo(dest, position.x, position.y); }
void AdjustDirection(Direction);
void FaceDirection(Direction);
void ResetDirection();
void ResetSpeed();
//accessors and mutators //accessors and mutators
Vector2 SetPosition(Vector2 v) { return position = v; } Vector2 SetPosition(Vector2 v) { return position = v; }
@@ -55,12 +50,14 @@ public:
SpriteSheet* GetSprite() { return &sprite; } SpriteSheet* GetSprite() { return &sprite; }
private: private:
void CheckSpeed();
Vector2 position; Vector2 position;
Vector2 motion; Vector2 motion;
SpriteSheet sprite; SpriteSheet sprite;
//for moving diagonally //for moving diagonal
bool diagonal = false; bool limitSpeed = false;
}; };
#endif #endif
+5 -5
View File
@@ -29,12 +29,12 @@ enum class SceneList {
FIRST, FIRST,
//custom indexes //custom indexes
SPLASHSCREEN,
MAINMENU,
OPTIONSMENU,
LOBBYMENU,
INWORLD,
INCOMBAT, INCOMBAT,
INWORLD,
LOBBY,
MAINMENU,
OPTIONSCREEN,
SPLASHSCREEN,
}; };
#endif #endif
-74
View File
@@ -1,74 +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 BASESCENE_HPP_
#define BASESCENE_HPP_
#include "scene_list.hpp"
#include "SDL/SDL.h"
class BaseScene {
public:
//Public access members
BaseScene();
virtual ~BaseScene();
//Program control
static SDL_Surface* SetScreen(int w, int h, int bpp = 0, Uint32 flags = SDL_HWSURFACE|SDL_DOUBLEBUF);
static SDL_Surface* GetScreen();
SceneList SetNextScene(SceneList sceneIndex);
SceneList GetNextScene() const;
//Frame loop
virtual void RunFrame(double delta);
virtual void RenderFrame();
protected:
virtual void FrameStart() {}
virtual void HandleEvents();
virtual void Update(double delta) {}
virtual void FrameEnd() {}
virtual void Render(SDL_Surface* const screen) {}
//Event handlers
virtual void QuitEvent() { SetNextScene(SceneList::QUIT); }
virtual void MouseMotion(SDL_MouseMotionEvent const&) {}
virtual void MouseButtonDown(SDL_MouseButtonEvent const&) {}
virtual void MouseButtonUp(SDL_MouseButtonEvent const&) {}
virtual void KeyDown(SDL_KeyboardEvent const&) {}
virtual void KeyUp(SDL_KeyboardEvent const&) {}
#ifdef USE_EVENT_JOYSTICK
//TODO: joystick/gamepad support
#endif
#ifdef USE_EVENT_UNKNOWN
virtual void UnknownEvent(SDL_Event const&) {}
#endif
private:
static SDL_Surface* screen;
SceneList nextScene = SceneList::CONTINUE;
};
#endif
-315
View File
@@ -1,315 +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 "channels.hpp"
#include <stdexcept>
//-------------------------
//Public access members
//-------------------------
InWorld::InWorld(ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex):
config(*argConfig),
network(*argNetwork),
clientIndex(*argClientIndex)
{
//setup the utility objects
image.LoadSurface(config["dir.interface"] + "button_menu.bmp");
image.SetClipH(image.GetClipH()/3);
font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp");
//pass the utility objects
disconnectButton.SetImage(&image);
disconnectButton.SetFont(&font);
shutDownButton.SetImage(&image);
shutDownButton.SetFont(&font);
//set the button positions
disconnectButton.SetX(50);
disconnectButton.SetY(50 + image.GetClipH() * 0);
shutDownButton.SetX(50);
shutDownButton.SetY(50 + image.GetClipH() * 1);
//set the button texts
disconnectButton.SetText("Disconnect");
shutDownButton.SetText("Shut Down");
//create the server-side player object
NetworkPacket packet;
packet.meta.type = NetworkPacket::Type::PLAYER_NEW;
packet.playerInfo.clientIndex = clientIndex;
snprintf(packet.playerInfo.handle, PACKET_STRING_SIZE, "%s", config["player.handle"].c_str());
snprintf(packet.playerInfo.avatar, PACKET_STRING_SIZE, "%s", config["player.avatar"].c_str());
packet.playerInfo.position = {0,0};
packet.playerInfo.motion = {0,0};
//send it
network.Send(Channels::SERVER, &packet, sizeof(NetworkPacket));
//request a sync
packet.meta.type = NetworkPacket::Type::SYNCHRONIZE;
network.Send(Channels::SERVER, &packet, sizeof(NetworkPacket));
}
InWorld::~InWorld() {
//
}
//-------------------------
//Frame loop
//-------------------------
void InWorld::FrameStart() {
//
}
void InWorld::Update(double delta) {
//suck in all waiting packets
NetworkPacket packet;
while(network.Receive()) {
memcpy(&packet, network.GetInData(), sizeof(NetworkPacket));
packet.meta.srcAddress = network.GetInPacket()->address;
HandlePacket(packet);
}
for (auto& it : playerCharacters) {
it.second.Update(delta);
}
}
void InWorld::FrameEnd() {
//
}
void InWorld::Render(SDL_Surface* const screen) {
for (auto& it : playerCharacters) {
it.second.DrawTo(screen);
}
disconnectButton.DrawTo(screen);
shutDownButton.DrawTo(screen);
}
//-------------------------
//Event handlers
//-------------------------
void InWorld::QuitEvent() {
//exit the game AND the server
RequestDisconnect();
}
void InWorld::MouseMotion(SDL_MouseMotionEvent const& motion) {
disconnectButton.MouseMotion(motion);
shutDownButton.MouseMotion(motion);
}
void InWorld::MouseButtonDown(SDL_MouseButtonEvent const& button) {
disconnectButton.MouseButtonDown(button);
shutDownButton.MouseButtonDown(button);
}
void InWorld::MouseButtonUp(SDL_MouseButtonEvent const& button) {
if (disconnectButton.MouseButtonUp(button) == Button::State::HOVER) {
RequestDisconnect();
}
if (shutDownButton.MouseButtonUp(button) == Button::State::HOVER) {
RequestShutDown();
}
}
void InWorld::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE: {
QuitEvent();
}
break;
//player movement
case SDLK_LEFT:
if (localCharacter) {
localCharacter->AdjustDirection(PlayerCharacter::Direction::WEST);
SendState();
}
break;
case SDLK_RIGHT:
if (localCharacter) {
localCharacter->AdjustDirection(PlayerCharacter::Direction::EAST);
SendState();
}
break;
case SDLK_UP:
if (localCharacter) {
localCharacter->AdjustDirection(PlayerCharacter::Direction::NORTH);
SendState();
}
break;
case SDLK_DOWN:
if (localCharacter) {
localCharacter->AdjustDirection(PlayerCharacter::Direction::SOUTH);
SendState();
}
break;
}
}
void InWorld::KeyUp(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
//player movement
case SDLK_LEFT:
if (localCharacter) {
localCharacter->AdjustDirection(PlayerCharacter::Direction::EAST);
SendState();
}
break;
case SDLK_RIGHT:
if (localCharacter) {
localCharacter->AdjustDirection(PlayerCharacter::Direction::WEST);
SendState();
}
break;
case SDLK_UP:
if (localCharacter) {
localCharacter->AdjustDirection(PlayerCharacter::Direction::SOUTH);
SendState();
}
break;
case SDLK_DOWN:
if (localCharacter) {
localCharacter->AdjustDirection(PlayerCharacter::Direction::NORTH);
SendState();
}
break;
}
}
void InWorld::HandlePacket(NetworkPacket packet) {
switch(packet.meta.type) {
case NetworkPacket::Type::DISCONNECT:
HandleDisconnect(packet);
break;
case NetworkPacket::Type::PLAYER_NEW:
HandlePlayerNew(packet);
break;
case NetworkPacket::Type::PLAYER_DELETE:
HandlePlayerDelete(packet);
break;
case NetworkPacket::Type::PLAYER_UPDATE:
HandlePlayerUpdate(packet);
break;
//handle errors
default:
throw(std::runtime_error("Unknown NetworkPacket::Type encountered"));
break;
}
}
void InWorld::HandleDisconnect(NetworkPacket packet) {
network.Unbind(Channels::SERVER);
clientIndex = -1;
SetNextScene(SceneList::MAINMENU);
}
void InWorld::HandlePlayerNew(NetworkPacket packet) {
if (playerCharacters.find(packet.playerInfo.playerIndex) != playerCharacters.end()) {
throw(std::runtime_error("Cannot create duplicate players"));
}
playerCharacters[packet.playerInfo.playerIndex].GetSprite()->LoadSurface(config["dir.sprites"] + packet.playerInfo.avatar, 4, 4);
playerCharacters[packet.playerInfo.playerIndex].SetPosition(packet.playerInfo.position);
playerCharacters[packet.playerInfo.playerIndex].SetMotion(packet.playerInfo.motion);
playerCharacters[packet.playerInfo.playerIndex].ResetDirection();
//catch this client's player object
if (packet.playerInfo.clientIndex == clientIndex && !localCharacter) {
playerIndex = packet.playerInfo.playerIndex;
localCharacter = &playerCharacters[playerIndex];
}
}
void InWorld::HandlePlayerDelete(NetworkPacket packet) {
if (playerCharacters.find(packet.playerInfo.playerIndex) == playerCharacters.end()) {
throw(std::runtime_error("Cannot delete non-existant players"));
}
playerCharacters.erase(packet.playerInfo.playerIndex);
//catch this client's player object
if (packet.playerInfo.clientIndex == clientIndex) {
playerIndex = -1;
localCharacter = nullptr;
}
}
void InWorld::HandlePlayerUpdate(NetworkPacket packet) {
if (playerCharacters.find(packet.playerInfo.playerIndex) == playerCharacters.end()) {
HandlePlayerNew(packet);
return;
}
//update only if the message didn't originate from here
if (packet.playerInfo.clientIndex != clientIndex) {
playerCharacters[packet.playerInfo.playerIndex].SetPosition(packet.playerInfo.position);
playerCharacters[packet.playerInfo.playerIndex].SetMotion(packet.playerInfo.motion);
}
playerCharacters[packet.playerInfo.playerIndex].ResetDirection();
}
void InWorld::SendState() {
NetworkPacket packet;
packet.meta.type = NetworkPacket::Type::PLAYER_UPDATE;
packet.playerInfo.clientIndex = clientIndex;
packet.playerInfo.playerIndex = playerIndex;
// snprintf(packet.playerInfo.handle, PACKET_STRING_SIZE, "%s", config["player.handle"].c_str());
// snprintf(packet.playerInfo.avatar, PACKET_STRING_SIZE, "%s", config["player.avatar"].c_str());
packet.playerInfo.position = localCharacter->GetPosition();
packet.playerInfo.motion = localCharacter->GetMotion();
network.Send(Channels::SERVER, &packet, sizeof(NetworkPacket));
}
void InWorld::RequestDisconnect() {
//send a disconnect request
NetworkPacket packet;
packet.meta.type = NetworkPacket::Type::DISCONNECT;
packet.clientInfo.index = clientIndex;
network.Send(Channels::SERVER, &packet, sizeof(NetworkPacket));
}
void InWorld::RequestShutDown() {
//send a shutdown request
NetworkPacket packet;
packet.meta.type = NetworkPacket::Type::SHUTDOWN;
packet.clientInfo.index = clientIndex;
network.Send(Channels::SERVER, &packet, sizeof(NetworkPacket));
}
-196
View File
@@ -1,196 +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 "lobby_menu.hpp"
#include "channels.hpp"
#include <stdexcept>
//-------------------------
//Public access members
//-------------------------
LobbyMenu::LobbyMenu(ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex):
config(*argConfig),
network(*argNetwork),
clientIndex(*argClientIndex)
{
//setup the utility objects
image.LoadSurface(config["dir.interface"] + "button_menu.bmp");
image.SetClipH(image.GetClipH()/3);
font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp");
//pass the utility objects
search.SetImage(&image);
search.SetFont(&font);
join.SetImage(&image);
join.SetFont(&font);
back.SetImage(&image);
back.SetFont(&font);
//set the button positions
search.SetX(50);
search.SetY(50 + image.GetClipH() * 0);
join.SetX(50);
join.SetY(50 + image.GetClipH() * 1);
back.SetX(50);
back.SetY(50 + image.GetClipH() * 2);
//set the button texts
search.SetText("Search");
join.SetText("Join");
back.SetText("Back");
//set the server list's position
listBox = {300, 50, 200, font.GetCharH()};
}
LobbyMenu::~LobbyMenu() {
//
}
//-------------------------
//Frame loop
//-------------------------
void LobbyMenu::FrameStart() {
//
}
void LobbyMenu::Update(double delta) {
//suck in all waiting packets
NetworkPacket packet;
while(network.Receive()) {
memcpy(&packet, network.GetInData(), sizeof(NetworkPacket));
packet.meta.srcAddress = network.GetInPacket()->address;
HandlePacket(packet);
}
}
void LobbyMenu::FrameEnd() {
//
}
void LobbyMenu::Render(SDL_Surface* const screen) {
search.DrawTo(screen);
join.DrawTo(screen);
back.DrawTo(screen);
for (int i = 0; i < serverInfo.size(); i++) {
//draw the selected server's highlight
if (selection == &serverInfo[i]) {
SDL_Rect r = listBox;
r.y += i * listBox.h;
SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 255, 127, 39));
}
//draw the server name
font.DrawStringTo(serverInfo[i].name, screen, listBox.x, listBox.y + i*listBox.h);
}
}
//-------------------------
//Event handlers
//-------------------------
void LobbyMenu::MouseMotion(SDL_MouseMotionEvent const& motion) {
search.MouseMotion(motion);
join.MouseMotion(motion);
back.MouseMotion(motion);
}
void LobbyMenu::MouseButtonDown(SDL_MouseButtonEvent const& button) {
search.MouseButtonDown(button);
join.MouseButtonDown(button);
back.MouseButtonDown(button);
}
void LobbyMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) {
if (search.MouseButtonUp(button) == Button::State::HOVER) {
//broadcast to the network, or a specific server
NetworkPacket packet;
packet.meta.type = NetworkPacket::Type::BROADCAST_REQUEST;
network.Send(config["server.host"].c_str(), config.Int("server.port"), reinterpret_cast<void*>(&packet), sizeof(NetworkPacket));
//reset the server list
serverInfo.clear();
selection = nullptr;
}
else if (join.MouseButtonUp(button) == Button::State::HOVER && selection != nullptr) {
//join the selected server
NetworkPacket packet;
packet.meta.type = NetworkPacket::Type::JOIN_REQUEST;
network.Send(&selection->address, &packet, sizeof(NetworkPacket));
selection = nullptr;
}
else if (back.MouseButtonUp(button) == Button::State::HOVER) {
SetNextScene(SceneList::MAINMENU);
}
else if (
//has the user selected a server on the list?
button.x > listBox.x &&
button.x < listBox.x + listBox.w &&
button.y > listBox.y &&
button.y < listBox.y + listBox.h * serverInfo.size()
) {
selection = &serverInfo[(button.y - listBox.y)/listBox.h];
}
else {
selection = nullptr;
}
}
void LobbyMenu::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE:
SetNextScene(SceneList::MAINMENU);
break;
}
}
void LobbyMenu::KeyUp(SDL_KeyboardEvent const& key) {
//
}
void LobbyMenu::HandlePacket(NetworkPacket packet) {
switch(packet.meta.type) {
case NetworkPacket::Type::BROADCAST_RESPONSE: {
ServerInformation server;
server.name = packet.serverInfo.name;
server.address = packet.meta.srcAddress;
serverInfo.push_back(server);
}
break;
case NetworkPacket::Type::JOIN_RESPONSE:
clientIndex = packet.clientInfo.index;
network.Bind(&packet.meta.srcAddress, Channels::SERVER);
SetNextScene(SceneList::INWORLD);
break;
//handle errors
default:
throw(std::runtime_error("Unknown NetworkPacket::Type encountered"));
break;
}
}
-43
View File
@@ -1,43 +0,0 @@
#config
INCLUDES+=. .. ../../common ../../common/graphics ../../common/map ../../common/network ../../common/ui
LIBS+=
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
#source
CXXSRC=$(wildcard *.cpp)
CSRC=$(wildcard *.c)
#objects
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
#output
OUTDIR=..
OUT=$(addprefix $(OUTDIR)/,libclient.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 $@ $<
$(OBJDIR)/%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean:
$(RM) *.o *.a *.exe
rebuild: clean all
-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.
*/
#include "splash_screen.hpp"
//-------------------------
//Public access members
//-------------------------
SplashScreen::SplashScreen(ConfigUtility* const argConfig):
config(*argConfig)
{
logo.LoadSurface(config["dir.logos"] + "krstudios.bmp");
startTick = std::chrono::steady_clock::now();
}
SplashScreen::~SplashScreen() {
//
}
//-------------------------
//Frame loop
//-------------------------
void SplashScreen::Update(double delta) {
if (std::chrono::steady_clock::now() - startTick > std::chrono::duration<int>(1)) {
SetNextScene(SceneList::MAINMENU);
}
}
void SplashScreen::Render(SDL_Surface* const screen) {
logo.DrawTo(screen, (screen->w - logo.GetClipW()) / 2, (screen->h - logo.GetClipH()) / 2);
}
+86
View File
@@ -0,0 +1,86 @@
/* 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 (std::chrono::steady_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") + "/pk_white_8.bmp");
surfaceMgr->Load("button", configUtil->String("interface") + "/button_menu.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
}
@@ -23,29 +23,31 @@
#define SPLASHSCREEN_HPP_ #define SPLASHSCREEN_HPP_
#include "base_scene.hpp" #include "base_scene.hpp"
#include "singleton.hpp"
#include "config_utility.hpp" #include "config_utility.hpp"
#include "surface_manager.hpp"
#include "image.hpp" #include "image.hpp"
#include <chrono> #include <chrono>
class SplashScreen : public BaseScene { class SplashScreen : public BaseScene {
public: public:
//Public access members /* Public access members */
SplashScreen(ConfigUtility* const); SplashScreen();
~SplashScreen(); ~SplashScreen();
protected: protected:
//Frame loop /* Frame loop */
void Update(double delta); void RunFrame(double delta);
void Render(SDL_Surface* const); void RenderFrame();
void LoadResources();
//globals bool loaded = false;
ConfigUtility& config; ConfigUtility* configUtil = Singleton<ConfigUtility>::Get();
SurfaceManager* surfaceMgr = Singleton<SurfaceManager>::Get();
//members
std::chrono::steady_clock::time_point startTick;
Image logo; Image logo;
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
}; };
#endif #endif
+26 -18
View File
@@ -23,6 +23,13 @@
#include <stdexcept> #include <stdexcept>
void Button::Setup(Sint16 i, Sint16 j, SDL_Surface* bg, SDL_Surface* fg, std::string t) {
x = i;
y = j;
SetSurfaces(bg, fg);
SetText(t);
}
Button::State Button::MouseMotion(SDL_MouseMotionEvent const& motion) { Button::State Button::MouseMotion(SDL_MouseMotionEvent const& motion) {
return CalcState(motion.x, motion.y, motion.state & SDL_BUTTON_LMASK); return CalcState(motion.x, motion.y, motion.state & SDL_BUTTON_LMASK);
} }
@@ -42,40 +49,41 @@ Button::State Button::MouseButtonUp(SDL_MouseButtonEvent const& button) {
} }
void Button::DrawTo(SDL_Surface* const dest) { void Button::DrawTo(SDL_Surface* const dest) {
if (!image || !font) { image.DrawTo(dest, x, y);
throw(std::runtime_error("Surface not set for Button")); font.DrawStringTo(text, dest, textX + x, textY + y);
} }
image->SetClipY(state * image->GetClipH());
image->DrawTo(dest, x, y); void Button::SetSurfaces(SDL_Surface* bg, SDL_Surface* fg) {
font->DrawStringTo(text, dest, textX + x, textY + y); //graphical stuff
image.SetSurface(bg);
image.SetClipH(image.GetClipH() / 3); //3 phases, vertical storage
font.SetSurface(fg);
//reset textX & textY
SetText(text);
} }
std::string Button::SetText(std::string t) { std::string Button::SetText(std::string t) {
if (!image || !font) {
throw(std::runtime_error("Surface not set for Button"));
}
//one line, cache the position //one line, cache the position
text = t; text = t;
textX = (image->GetClipW() / 2) - (font->GetCharW() * text.size() / 2); textX = (image.GetClipW() / 2) - (font.GetCharW() * text.size() / 2);
textY = (image->GetClipH() / 2) - (font->GetCharH() / 2); textY = (image.GetClipH() / 2) - (font.GetCharH() / 2);
return text; return text;
} }
Button::State Button::CalcState(Sint16 i, Sint16 j, bool leftPressed) { Button::State Button::CalcState(Sint16 i, Sint16 j, bool leftPressed) {
if (!image || !font) { if (i < x || i > (x + image.GetClipW()) ||
throw(std::runtime_error("Surface not set for Button")); j < y || j > (y + image.GetClipH())
}
//if out of bounds
if (i < x || i >= (x + image->GetClipW()) ||
j < y || j >= (y + image->GetClipH())
) { ) {
image.SetClipY(0);
return state = State::NORMAL; return state = State::NORMAL;
} }
if (leftPressed) { if (leftPressed) {
image.SetClipY(image.GetClipH()*2);
return state = State::PRESSED; return state = State::PRESSED;
} }
else { else {
image.SetClipY(image.GetClipH());
return state = State::HOVER; return state = State::HOVER;
} }
} }
+21 -35
View File
@@ -27,66 +27,52 @@
#include <string> #include <string>
/* 3-phases, no toggle, centred text //3-phases, no toggle, centred text
* This class uses the size of the provided image as its bounds. Also,
* The provided image should be formatted correctly.
*
* The button's image should be divided into 3 sections virtucally,
* which act as the different button images. The clip width & height of the
* Image should be set manually, and the height should be 1/3 of the total
* graphical data.
*/
class Button { class Button {
public: public:
enum State { enum class State {
NORMAL = 0, HOVER = 1, PRESSED = 2 NORMAL, HOVER, PRESSED
}; };
Button() = default; Button() = default;
~Button() = default; Button(Sint16 x, Sint16 y, SDL_Surface* bg, SDL_Surface* fg, std::string t = "") { Setup(x, y, bg, fg, t); }
//handle input void Setup(Sint16 x, Sint16 y, SDL_Surface* bg, SDL_Surface* fg, std::string text = "");
//return the current state
State MouseMotion(SDL_MouseMotionEvent const&); State MouseMotion(SDL_MouseMotionEvent const&);
State MouseButtonDown(SDL_MouseButtonEvent const&); State MouseButtonDown(SDL_MouseButtonEvent const&);
State MouseButtonUp(SDL_MouseButtonEvent const&); State MouseButtonUp(SDL_MouseButtonEvent const&);
State GetState() const { return state; }
//yet another draw function //yet another draw function
void DrawTo(SDL_Surface* const); void DrawTo(SDL_Surface* const);
//accessors and mutators //simple accessors and mutators
Image* SetImage(Image* const ptr) { return image = ptr; }
Image* GetImage() { return image; }
RasterFont* SetFont(RasterFont* const ptr) { return font = ptr; }
RasterFont* GetFont() { return font; }
Sint16 SetX(Sint16 i) { return x = i; } Sint16 SetX(Sint16 i) { return x = i; }
Sint16 SetY(Sint16 i) { return y = i; } Sint16 SetY(Sint16 i) { return y = i; }
Sint16 GetX() const { return x; } Sint16 GetX() const { return x; }
Sint16 GetY() const { return y; } Sint16 GetY() const { return y; }
Sint16 SetTextX(Sint16 i) { return textX = i; } void SetSurfaces(SDL_Surface* bg, SDL_Surface* fg);
Sint16 SetTextY(Sint16 i) { return textY = i; }
Sint16 GetTextX() const { return textX; }
Sint16 GetTextY() const { return textY; }
State SetState(State s) { return state = s; } std::string SetText(std::string t);
State GetState() const { return state; }
std::string SetText(std::string);
std::string GetText() const { return text; } std::string GetText() const { return text; }
//raw access, be careful
Image* GetImage() { return &image; }
RasterFont* GetFont() { return &font; }
//debug
Sint16 GetTextX() const { return textX; }
Sint16 GetTextY() const { return textY; }
private: private:
State CalcState(Sint16 x, Sint16 y, bool leftPressed); State CalcState(Sint16 x, Sint16 y, bool leftPressed);
//point to the provided external objects
Image* image = nullptr;
RasterFont* font = nullptr;
//positions
Sint16 x = 0, y = 0; Sint16 x = 0, y = 0;
Sint16 textX = 0, textY = 0; Sint16 textX = 0, textY = 0; //prevent recalc every loop
Image image;
// RasterFont font;
State state = State::NORMAL; State state = State::NORMAL;
std::string text; std::string text;
}; };
+1 -30
View File
@@ -21,9 +21,8 @@
*/ */
#include "config_utility.hpp" #include "config_utility.hpp"
#include <cstdlib>
#include <fstream>
#include <stdexcept> #include <stdexcept>
#include <fstream>
using namespace std; using namespace std;
@@ -75,31 +74,3 @@ void ConfigUtility::Load(string fname) {
is.close(); is.close();
} }
std::string& ConfigUtility::String(std::string s) {
return table[s];
}
int ConfigUtility::Integer(std::string s) {
std::map<std::string, std::string>::iterator it = table.find(s);
if (it == table.end()) {
return 0;
}
return atoi(it->second.c_str());
}
double ConfigUtility::Double(std::string s) {
std::map<std::string, std::string>::iterator it = table.find(s);
if (it == table.end()) {
return 0.0;
}
return atof(it->second.c_str());
}
bool ConfigUtility::Boolean(std::string s) {
std::map<std::string, std::string>::iterator it = table.find(s);
if (it == table.end()) {
return false;
}
return it->second == "true";
}
+19 -11
View File
@@ -24,32 +24,40 @@
#include <map> #include <map>
#include <string> #include <string>
#include <cstdlib>
class ConfigUtility { class ConfigUtility {
public: public:
ConfigUtility() = default; ConfigUtility() {}
ConfigUtility(std::string s) { Load(s); } ConfigUtility(std::string s) { Load(s); }
void Load(std::string fname); void Load(std::string fname);
//convert to a type std::string String(std::string s) {
std::string& String(std::string); return table[s];
int Integer(std::string); }
double Double(std::string); const char* CString(std::string s) {
bool Boolean(std::string); return table[s].c_str();
}
int Integer(std::string s) {
return atoi(table[s].c_str());
}
double Double(std::string s) {
return atof(table[s].c_str());
}
bool Boolean(std::string s) {
return table[s] == "true";
}
//shorthand
std::string& operator[](std::string s) { std::string& operator[](std::string s) {
return String(s); return table[s];
} }
int Int(std::string s) { int Int(std::string s) {
return Integer(s); return Integer(s);
} }
bool Bool(std::string s) { int Bool(std::string s) {
return Boolean(s); return Boolean(s);
} }
//OO breaker
std::map<std::string, std::string>* GetMap() { std::map<std::string, std::string>* GetMap() {
return &table; return &table;
} }
+8 -10
View File
@@ -19,18 +19,16 @@
* 3. This notice may not be removed or altered from any source * 3. This notice may not be removed or altered from any source
* distribution. * distribution.
*/ */
#ifndef SCENELIST_HPP_ #ifndef DEFINES_HPP_
#define SCENELIST_HPP_ #define DEFINES_HPP_
enum class SceneList { #define GAME_CHANNEL 0
//these are reserved #define CHAT_CHANNEL 1
QUIT,
CONTINUE,
FIRST,
//custom indexes #define WALKING_SPEED 140
TESTIFICATESCENE,
EDITORSCENE, enum class CardinalDirection {
NORTH, SOUTH, EAST, WEST
}; };
#endif #endif
+18 -16
View File
@@ -19,24 +19,26 @@
* 3. This notice may not be removed or altered from any source * 3. This notice may not be removed or altered from any source
* distribution. * distribution.
*/ */
#include "editor_application.hpp" #include "frame_rate.hpp"
#include <stdexcept> #include <chrono>
#include <iostream>
using namespace std; typedef std::chrono::high_resolution_clock Clock;
int main(int, char**) { static int frameCount = 0;
cout << "Beginning editor" << endl; static int lastFrameRate = 0;
try { static Clock::time_point tick = Clock::now();
EditorApplication::GetInstance()->Init();
EditorApplication::GetInstance()->Proc(); int clockFrameRate() {
EditorApplication::GetInstance()->Quit(); frameCount++;
if (Clock::now() - tick >= std::chrono::duration<int>(1)) {
lastFrameRate = frameCount;
frameCount = 0;
tick = Clock::now();
} }
catch(exception& e) { return lastFrameRate;
cerr << "Fatal exception thrown: " << e.what() << endl; }
return 1;
} int getFrameRate() {
cout << "Clean exit" << endl; return lastFrameRate;
return 0;
} }
+4 -14
View File
@@ -19,20 +19,10 @@
* 3. This notice may not be removed or altered from any source * 3. This notice may not be removed or altered from any source
* distribution. * distribution.
*/ */
#ifndef CLIENT_HPP_ #ifndef FRAMERATE_HPP_
#define CLIENT_HPP_ #define FRAMERATE_HPP_
#include "SDL/SDL_net.h" int clockFrameRate();
int getFrameRate();
#include <map>
/* Hold the client info.
*/
struct Client {
IPaddress address;
};
typedef std::map<int, Client> ClientMap;
#endif #endif
-102
View File
@@ -1,102 +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 "sprite_sheet.hpp"
#include <stdexcept>
#include <sstream>
void SpriteSheet::Update(double delta) {
if (delay && (tick += delta) >= delay) {
if (++xIndex >= xCount) {
xIndex = 0;
}
tick = 0;
}
image.SetClipX(xIndex * image.GetClipW());
image.SetClipY(yIndex * image.GetClipH());
}
SDL_Surface* SpriteSheet::LoadSurface(std::string fname, Uint16 xCellCount, Uint16 yCellCount) {
image.LoadSurface(fname);
xCount = xCellCount;
yCount = yCellCount;
image.SetClipW(image.GetSurface()->w / xCount);
image.SetClipH(image.GetSurface()->h / yCount);
xIndex = yIndex = 0;
delay = tick = 0.0;
}
SDL_Surface* SpriteSheet::SetSurface(SDL_Surface* surface, Uint16 xCellCount, Uint16 yCellCount) {
image.SetSurface(surface);
xCount = xCellCount;
yCount = yCellCount;
image.SetClipW(image.GetSurface()->w / xCount);
image.SetClipH(image.GetSurface()->h / yCount);
xIndex = yIndex = 0;
delay = tick = 0.0;
}
void SpriteSheet::FreeSurface() {
image.FreeSurface();
xCount = yCount = 0;
xIndex = yIndex = 0;
delay = tick = 0.0;
}
Uint16 SpriteSheet::SetXCount(Uint16 i) {
xIndex = 0;
return xCount = i;
}
Uint16 SpriteSheet::SetYCount(Uint16 i) {
yIndex = 0;
return yCount = i;
}
Uint16 SpriteSheet::SetXIndex(Uint16 i) {
if (i > xCount) {
std::ostringstream os;
os << "Cannot set x index to " << i;
throw(std::invalid_argument(os.str()));
}
return xIndex = i;
}
Uint16 SpriteSheet::SetYIndex(Uint16 i) {
if (i > yCount) {
std::ostringstream os;
os << "Cannot set y index to " << i;
throw(std::invalid_argument(os.str()));
}
return yIndex = i;
}
double SpriteSheet::SetDelay(double d) {
tick = 0;
return delay = d;
}
+12 -80
View File
@@ -22,88 +22,16 @@
#include "image.hpp" #include "image.hpp"
#include <stdexcept> #include <stdexcept>
#include <sstream>
Image& Image::operator=(Image const& rhs) {
//don't screw yourself
if (this == &rhs) {
return *this;
}
FreeSurface();
//Copy the other Image's stuff
surface = rhs.surface;
clip = rhs.clip;
local = false;
}
Image& Image::operator=(Image&& rhs) {
//don't screw yourself
if (this == &rhs) {
return *this;
}
FreeSurface();
//Steal the other Image's stuff
surface = rhs.surface;
clip = rhs.clip;
local = rhs.local;
rhs.surface = nullptr;
rhs.clip = {0, 0, 0, 0};
rhs.local = false;
}
SDL_Surface* Image::LoadSurface(std::string fname) { SDL_Surface* Image::LoadSurface(std::string fname) {
FreeSurface();
SDL_Surface* p = SDL_LoadBMP(fname.c_str()); SDL_Surface* p = SDL_LoadBMP(fname.c_str());
if (!p) { if (!p) {
std::ostringstream os; throw(std::runtime_error(std::string() + "Failed to load file: " + fname));
os << "Failed to load file: " << fname;
throw(std::runtime_error(os.str()));
} }
surface = p; surface = p;
SetTransparentColor(255, 0, 255); //default
clip = {0, 0, (Uint16)surface->w, (Uint16)surface->h}; clip = {0, 0, (Uint16)surface->w, (Uint16)surface->h};
local = true; local = true;
SetTransparentColor(255, 0, 255); //default
return surface;
}
SDL_Surface* Image::CreateSurface(Uint16 w, Uint16 h) {
FreeSurface();
Uint32 rmask, gmask, bmask, amask;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff000000;
gmask = 0x00ff0000;
bmask = 0x0000ff00;
amask = 0x000000ff;
#else
rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000;
amask = 0xff000000;
#endif
SDL_Surface* p = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, rmask, gmask, bmask, amask);
if (!p) {
throw(std::runtime_error("Failed to create Image surface"));
}
surface = p;
clip = {0, 0, (Uint16)surface->w, (Uint16)surface->h};
local = true;
SetTransparentColor(255, 0, 255); //default
return surface;
}
SDL_Surface* Image::SetSurface(SDL_Surface* p) {
FreeSurface();
if (!p) {
throw(std::invalid_argument("No surface pointer provided"));
}
surface = p;
clip = {0, 0, (Uint16)surface->w, (Uint16)surface->h};
local = false;
return surface; return surface;
} }
@@ -116,6 +44,16 @@ void Image::FreeSurface() {
clip = {0, 0, 0, 0}; clip = {0, 0, 0, 0};
} }
SDL_Surface* Image::SetSurface(SDL_Surface* p) {
if (!p) {
throw(std::invalid_argument("No surface pointer provided"));
}
surface = p;
clip = {0, 0, (Uint16)surface->w, (Uint16)surface->h};
local = false;
return surface;
}
void Image::DrawTo(SDL_Surface* dest, Sint16 x, Sint16 y) { void Image::DrawTo(SDL_Surface* dest, Sint16 x, Sint16 y) {
if (!surface) { if (!surface) {
throw(std::logic_error("No image surface to draw")); throw(std::logic_error("No image surface to draw"));
@@ -128,9 +66,6 @@ void Image::SetTransparentColor(Uint8 r, Uint8 g, Uint8 b) {
if (!surface) { if (!surface) {
throw(std::logic_error("Failed to set the transparent color")); throw(std::logic_error("Failed to set the transparent color"));
} }
if (!local) {
throw(std::logic_error("Cannot set the transparent color of a non-local surface"));
}
SDL_SetColorKey(surface, SDL_SRCCOLORKEY, SDL_MapRGB(surface->format, r, g, b)); SDL_SetColorKey(surface, SDL_SRCCOLORKEY, SDL_MapRGB(surface->format, r, g, b));
} }
@@ -138,8 +73,5 @@ void Image::ClearTransparentColor() {
if (!surface) { if (!surface) {
throw(std::logic_error("Failed to clear the transparent color")); throw(std::logic_error("Failed to clear the transparent color"));
} }
if (!local) {
throw(std::logic_error("Cannot clear the transparent color of a non-local surface"));
}
SDL_SetColorKey(surface, 0, 0); SDL_SetColorKey(surface, 0, 0);
} }
+3 -10
View File
@@ -28,21 +28,14 @@
class Image { class Image {
public: public:
Image() = default; Image() = default;
Image(Image const& rhs) { *this = rhs; }
Image(Image&& rhs) { *this = std::move(rhs); }
Image(std::string fname) { LoadSurface(fname); }
Image(Uint16 w, Uint16 h) { CreateSurface(w, h); }
Image(SDL_Surface* p) { SetSurface(p); } Image(SDL_Surface* p) { SetSurface(p); }
~Image() { FreeSurface(); } ~Image() { FreeSurface(); }
Image& operator=(Image const&);
Image& operator=(Image&&);
SDL_Surface* LoadSurface(std::string fname); SDL_Surface* LoadSurface(std::string fname);
SDL_Surface* CreateSurface(Uint16 w, Uint16 h); void FreeSurface();
SDL_Surface* SetSurface(SDL_Surface*); SDL_Surface* SetSurface(SDL_Surface*);
SDL_Surface* GetSurface() const { return surface; } SDL_Surface* GetSurface() const { return surface; }
void FreeSurface();
void DrawTo(SDL_Surface* const, Sint16 x, Sint16 y); void DrawTo(SDL_Surface* const, Sint16 x, Sint16 y);
@@ -60,7 +53,7 @@ public:
Uint16 GetClipW() const { return clip.w; } Uint16 GetClipW() const { return clip.w; }
Uint16 GetClipH() const { return clip.h; } Uint16 GetClipH() const { return clip.h; }
bool GetLocal() const { return local; } bool GetLocal() { return local; }
void SetTransparentColor(Uint8 r, Uint8 g, Uint8 b); void SetTransparentColor(Uint8 r, Uint8 g, Uint8 b);
void ClearTransparentColor(); void ClearTransparentColor();
+7 -16
View File
@@ -1,29 +1,23 @@
#config #config
INCLUDES+=. LOCALLIBS=
LIBS+= LIB=
INCLUDES=
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES)) CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
#source #source
CXXSRC=$(wildcard *.cpp) SRC=$(wildcard *.cpp)
CSRC=$(wildcard *.c)
#objects #objects
OBJDIR=obj OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o)) OBJ=$(addprefix $(OBJDIR)/,$(SRC:.cpp=.o))
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
#output #output
OUTDIR=.. OUTDIR=../lib
OUT=$(addprefix $(OUTDIR)/,libcommon.a) OUT=$(addprefix $(OUTDIR)/,libCommon.a)
#targets #targets
all: $(OBJ) $(OUT) all: $(OBJ) $(OUT)
ar -crs $(OUT) $(OBJ) ar -crs $(OUT) $(OBJ)
$(MAKE) -C graphics
$(MAKE) -C map
$(MAKE) -C network
$(MAKE) -C ui
$(OBJ): | $(OBJDIR) $(OBJ): | $(OBJDIR)
@@ -38,9 +32,6 @@ $(OUTDIR):
$(OBJDIR)/%.o: %.cpp $(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $< $(CXX) $(CXXFLAGS) -c -o $@ $<
$(OBJDIR)/%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean: clean:
$(RM) *.o *.a *.exe $(RM) *.o *.a *.exe
-43
View File
@@ -1,43 +0,0 @@
#config
INCLUDES+=. .. ../graphics
LIBS+=
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
#source
CXXSRC=$(wildcard *.cpp)
CSRC=$(wildcard *.c)
#objects
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
#output
OUTDIR=../..
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 $@ $<
$(OBJDIR)/%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean:
$(RM) *.o *.a *.exe
rebuild: clean all
-123
View File
@@ -1,123 +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 "region.hpp"
#include "utility.hpp"
#include <stdexcept>
#include <sstream>
Region::Region(int _x, int _y, int _w, int _h):
x(_x),
y(_y),
width(_w),
height(_h)
{
//make sure that the region's position lines up
if (x != snapToBase(width, x) || y != snapToBase(height, y)) {
std::ostringstream os;
os << "Region is unaligned; x: " << x << ", y: " << y << ", width: " << width << ", height: " << height;
throw(std::runtime_error(os.str()));
}
}
int Region::NewTileR(Tile const& tile) {
//return 1 for overwrite, 0 for insert
if (!InBoundsR(tile.x, tile.y)) {
std::ostringstream os;
os << "New tile location out of bounds: " <<
"(" << x << "," << y << ")->" <<
"(" << tile.x << "," << tile.y << ")"
;
throw(std::runtime_error(os.str()));
}
int ret = tiles.erase(tile);
tiles.insert(tile);
return ret;
}
Tile Region::GetTileR(int tx, int ty, int minDepth) {
std::set<Tile>::iterator ptr = tiles.begin();
//skip the tiles that are too deep
while(ptr != tiles.end()) {
if (ptr->depth >= minDepth) {
break;
}
ptr++;
}
//find the first tile here
while(ptr != tiles.end()) {
//bounds
if ((ptr->x <= tx) && (ptr->y <= ty) && (ptr->x + ptr->width > tx) && (ptr->y + ptr->height > ty)) {
break;
}
ptr++;
}
//found it
if (ptr != tiles.end()) {
return *ptr;
}
//a tileIndex of -1 is an error code, the rest is for show
return {0,0,0,-1,-1,-1};
}
int Region::DeleteTileR(Tile const& tile) {
if (!InBoundsR(tile.x, tile.y)) {
throw(std::runtime_error("Deleted tile location out of bounds"));
std::ostringstream os;
os << "Deleted tile location out of bounds: " <<
"(" << x << "," << y << ")->" <<
"(" << tile.x << "," << tile.y << ")"
;
throw(std::runtime_error(os.str()));
}
//sentinel/error code
if (tile.tileIndex == -1) {
return 0;
}
return tiles.erase(tile);
}
bool operator<(Region const& lhs, Region const& rhs) {
//sort by y -> x
if (lhs.y == rhs.y) {
return lhs.x < rhs.x;
}
return lhs.y < rhs.y;
}
inline bool operator>(Region const& lhs, Region const& rhs) {
//wrap the other operator
return rhs < lhs;
}
inline bool operator==(Region const& lhs, Region const& rhs) {
//comparisons work on the location ONLY
//this function is redundant as far as the std::set object is concerned
return (lhs.x == rhs.x) && (lhs.y == rhs.y);
}
-112
View File
@@ -1,112 +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 REGION_HPP_
#define REGION_HPP_
#include "tile.hpp"
#include <set>
/* A single section of the map.
* This class stores the tiles relative to it's own position, but
* there are functions for referencing the tiles' absolute position.
* These functions simply wrap the normal functions.
*/
class Region {
public:
Region() = delete;
Region(int x, int y, int width, int height);
~Region() = default;
//create and insert a new tile, overwriting an existing tile at that location
int NewTileR(Tile const& tile);
int NewTileA(Tile const& tile) {
//these can change, if the Tile class is changed
return NewTileR({
tile.x - x,
tile.y - y,
tile.depth,
tile.width,
tile.height,
tile.tileIndex
});
}
//find the first tile at this location, with the specified minimum depth
Tile GetTileR(int tx, int ty, int minDepth);
Tile GetTileA(int tx, int ty, int minDepth) {
return GetTileR(tx - x, ty - y, minDepth);
}
//wrap the other delete functions
int DeleteTileR(int tx, int ty, int minDepth) {
return DeleteTileR(GetTileR(tx, ty, minDepth));
}
int DeleteTileA(int tx, int ty, int minDepth) {
//explicitly skip one function call by adjusting from A to R
return DeleteTileR(GetTileR(tx - x, ty - y, minDepth));
}
//delete the specified tile
int DeleteTileR(Tile const& tile);
int DeleteTileA(Tile const& tile) {
//these can change, if the Tile class is changed
return DeleteTileR({
tile.x - x,
tile.y - y,
tile.depth,
tile.width,
tile.height,
tile.tileIndex
});
}
//find if the specified location exists within the region's bounds
bool InBoundsR(int i, int j) {
return (i >= 0) && (j >= 0) && (i < width) && (j < height);
}
bool InBoundsA(int i, int j) {
return InBoundsR(i - x, j - y);
}
//Raw accessors & mutators
int GetX() const { return x; }
int GetY() const { return y; }
int GetWidth() const { return width; }
int GetHeight() const { return height; }
std::set<Tile>* GetTiles() { return &tiles; }
//sorting the regions by the locations
friend bool operator<(Region const& lhs, Region const& rhs);
friend bool operator>(Region const& lhs, Region const& rhs);
friend bool operator==(Region const& lhs, Region const& rhs);
private:
int const x;
int const y;
int const width;
int const height;
std::set<Tile> tiles;
};
#endif
-121
View File
@@ -1,121 +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 "region_pager.hpp"
#include "utility.hpp"
#include <stdexcept>
#include <string>
RegionPager::RegionPager() {
//
}
RegionPager::~RegionPager() {
if (onDelete) {
for (auto& i : regionList) {
onDelete(&i);
}
}
}
Region* RegionPager::NewRegion(int x, int y) {
for (auto& i : regionList) {
if (i.GetX() == x && i.GetY() == y) {
throw(std::runtime_error("Duplicate Regions detected"));
}
}
regionList.push_front({x, y, regionWidth, regionHeight});
if (onNew) {
onNew(&regionList.front());
}
return &regionList.front();
}
Region* RegionPager::GetRegion(int x, int y) {
for (auto& i : regionList) {
if (i.GetX() == x && i.GetY() == y) {
return &i;
}
}
//create, insert and return
regionList.push_front({x, y, regionWidth, regionHeight});
if (onNew) {
onNew(&regionList.front());
}
return &regionList.front();
}
void RegionPager::DeleteRegion(int x, int y) {
for (std::list<Region>::iterator i = regionList.begin(); i != regionList.end(); i++) {
if (i->GetX() == x && i->GetY() == y) {
if (onDelete) {
onDelete(&(*i));
}
regionList.erase(i);
break;
}
}
}
void RegionPager::DrawTo(SDL_Surface* const dest, TileSheetManager* const sheetMgr, int camX, int camY) {
for (auto& regionIter : regionList) {
#ifdef DEBUG
//draw the region's location
SDL_Rect box = {
Sint16(regionIter.GetX() - camX),
Sint16(regionIter.GetY() - camY),
Uint16(regionIter.GetWidth()),
Uint16(regionIter.GetHeight())
};
SDL_FillRect(dest, &box, SDL_MapRGB(dest->format, 10, 10, 20));
#endif
//draw each tile
for (auto& tileIter : *regionIter.GetTiles()) {
sheetMgr->DrawTo(
dest,
tileIter.x + regionIter.GetX() - camX,
tileIter.y + regionIter.GetY() - camY,
tileIter.tileIndex
);
}
}
}
void RegionPager::Prune(int left, int top, int right, int bottom) {
std::list<Region>::iterator it = regionList.begin();
while(it != regionList.end()) {
if (it->GetX() >= right || it->GetY() >= bottom || it->GetX() + it->GetWidth() < left || it->GetY() + it->GetHeight() < top) {
if (onDelete) {
onDelete(&(*it));
}
regionList.erase(it);
it = regionList.begin();
continue;
}
it++;
}
}
-69
View File
@@ -1,69 +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 REGIONPAGER_HPP_
#define REGIONPAGER_HPP_
#include "region.hpp"
#include "tile_sheet_manager.hpp"
#include <list>
class RegionPager {
public:
//for simplicity and consistency
typedef void (*regionCallback_t)(Region* const);
RegionPager();
~RegionPager();
//these parameters MUST be multiples of the width & height
Region* NewRegion(int x, int y);
Region* GetRegion(int x, int y);
void DeleteRegion(int x, int y);
//call this to draw to the screen
void DrawTo(SDL_Surface* const, TileSheetManager* const, int camX, int camY);
//callback hooks
void SetOnNew(regionCallback_t f) { onNew = f; }
void SetOnDelete(regionCallback_t f) { onDelete = f; }
//params: Absolute values
void Prune(int left, int top, int right, int bottom);
//accessors and mutators
int SetWidth(int i) { return regionWidth = i; }
int SetHeight(int i) { return regionHeight = i; }
int GetWidth() const { return regionWidth; }
int GetHeight() const { return regionHeight; }
std::list<Region>* GetRegions() { return &regionList; }
private:
std::list<Region> regionList;
int regionWidth = 0, regionHeight = 0;
regionCallback_t onNew = nullptr;
regionCallback_t onDelete = nullptr;
};
#endif
-50
View File
@@ -1,50 +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 TILE_HPP_
#define TILE_HPP_
//explicitly a POD
struct Tile {
//position relative to the Region
int x, y, depth;
//graphics
int width, height;
int tileIndex;
Tile() = default;
Tile(int _x, int _y, int _depth, int _width, int _height, int _tileIndex) {
//The order of the arguments should be explicit
x = _x;
y = _y;
depth = _depth;
width = _width;
height = _height;
tileIndex = _tileIndex;
}
};
bool operator<(Tile const& lhs, Tile const& rhs);
bool operator>(Tile const& lhs, Tile const& rhs);
bool operator==(Tile const& lhs, Tile const& rhs);
#endif
-59
View File
@@ -1,59 +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 "tile_sheet.hpp"
#include <stdexcept>
void TileSheet::Load(std::string fname, Uint16 w, Uint16 h) {
//setup the image
image.LoadSurface(fname);
image.SetClipW(w);
image.SetClipH(h);
//get the tile counts
xCount = image.GetSurface()->w / w;
yCount = image.GetSurface()->h / h;
totalCount = xCount * yCount;
//set begin & end (usually temporary)
begin = 0;
end = totalCount;
}
void TileSheet::Unload() {
image.FreeSurface();
totalCount = xCount = yCount = 0;
begin = end = -1;
}
void TileSheet::DrawTo(SDL_Surface* const dest, int x, int y, int tileIndex) {
if (!InRange(tileIndex)) {
throw(std::invalid_argument("Tile index out of range"));
}
Sint16 clipX = (tileIndex-begin) % xCount * image.GetClipW();
Sint16 clipY = (tileIndex-begin) / xCount * image.GetClipH();
image.SetClipX(clipX);
image.SetClipY(clipY);
image.DrawTo(dest, x, y);
}
-70
View File
@@ -1,70 +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 TILESHEET_HPP_
#define TILESHEET_HPP_
#include "image.hpp"
#include <string>
/* The TileSheet class is used for drawing tiles of the map to the screen.
* This class also tracks the range of the tile images.
*/
class TileSheet {
public:
TileSheet() = default;
~TileSheet() = default;
//these load/set functions need to be followed by bookkeeping code
//w & h are the width & height of individual tiles
//TODO: rename these
void Load(std::string fname, Uint16 w, Uint16 h);
void Unload();
void DrawTo(SDL_Surface* const dest, int x, int y, int tileIndex);
bool InRange(int i) { return i >= begin && i < end; }
//accessors and mutators
Image* GetImage() { return &image; }
int GetTileW() const { return image.GetClipW(); }
int GetTileH() const { return image.GetClipH(); }
int GetTotalCount() const { return totalCount; }
int GetXCount() const { return xCount; }
int GetYCount() const { return yCount; }
int SetBegin(int i) { return begin = i; }
int SetEnd(int i) { return end = i; }
int GetBegin() const { return begin; }
int GetEnd() const { return end; }
private:
Image image;
//these are generated and used by internal processes
int totalCount = 0, xCount = 0, yCount = 0;
int begin = -1, end = -1;
};
#endif
-73
View File
@@ -1,73 +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 "tile_sheet_manager.hpp"
#include "utility.hpp"
#include <stdexcept>
TileSheet* TileSheetManager::LoadSheet(std::string fname, Uint16 w, Uint16 h) {
//get the key
std::string key = truncatePath(fname);
//don't override what's already here
if (sheetMap.find(key) != sheetMap.end()) {
throw(std::runtime_error("Cannot load duplicate tile sheets"));
}
//load & setup the sheet object
sheetMap[key].Load(fname, w, h);
sheetMap[key].SetBegin(rangeEnd);
rangeEnd += sheetMap[key].GetTotalCount();
sheetMap[key].SetEnd(rangeEnd);
//you can modify the object, say, during the save & load routines...
return &sheetMap[key];
}
TileSheet* TileSheetManager::GetSheet(std::string name) {
return &sheetMap.at(name);
}
TileSheet* TileSheetManager::GetSheetByIndex(int tileIndex) {
for (auto& it : sheetMap) {
if (it.second.InRange(tileIndex)) {
return &it.second;
}
}
return nullptr;
}
void TileSheetManager::UnloadSheet(std::string name) {
sheetMap.erase(name);
}
void TileSheetManager::DrawTo(SDL_Surface* const dest, int x, int y, int tileIndex) {
for (auto& it : sheetMap) {
if (it.second.InRange(tileIndex)) {
it.second.DrawTo(dest, x, y, tileIndex);
return;
}
}
//No matching tile index
throw(std::invalid_argument("Tile index is out of range of all tile sheets"));
}
-43
View File
@@ -1,43 +0,0 @@
#config
INCLUDES+=. ..
LIBS+=
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
#source
CXXSRC=$(wildcard *.cpp)
CSRC=$(wildcard *.c)
#objects
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
#output
OUTDIR=../..
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 $@ $<
$(OBJDIR)/%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean:
$(RM) *.o *.a *.exe
rebuild: clean all
+110
View File
@@ -0,0 +1,110 @@
/* 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 "singleton.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 = Singleton<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 = Singleton<UDPNetworkUtility>::Get();
SDL_SemWait(lock);
while(netUtil->Receive());
queue.clear();
SDL_SemPost(lock);
}
+34
View File
@@ -0,0 +1,34 @@
/* 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.hpp"
void beginQueueThread();
void endQueueThread();
void killQueueThread();
Packet peekNetworkPacket();
Packet popNetworkPacket();
void flushNetworkQueue();
#endif
@@ -19,54 +19,42 @@
* 3. This notice may not be removed or altered from any source * 3. This notice may not be removed or altered from any source
* distribution. * distribution.
*/ */
#ifndef NETWORKPACKET_HPP_ #ifndef PACKETTYPE_HPP_
#define NETWORKPACKET_HPP_ #define PACKETTYPE_HPP_
#include "SDL/SDL_net.h"
#include "vector2.hpp" #include "vector2.hpp"
#include "SDL/SDL_net.h"
#define PACKET_STRING_SIZE 100 #define PACKET_STRING_SIZE 100
#pragma pack(push, 0) #pragma pack(push, 0)
union NetworkPacket { union Packet {
//types of packets //the type of packet being sent
enum class Type { enum class Type {
//default: there is something wrong
NONE = 0, NONE = 0,
//not used
PING = 1, PING = 1,
PONG = 2, PONG = 2,
//Searching for a server to join
BROADCAST_REQUEST = 3, BROADCAST_REQUEST = 3,
BROADCAST_RESPONSE = 4, BROADCAST_RESPONSE = 4,
//try to join the server
JOIN_REQUEST = 5, JOIN_REQUEST = 5,
JOIN_RESPONSE = 6, JOIN_RESPONSE = 6,
//disconnect from the server
DISCONNECT = 7, DISCONNECT = 7,
//mass update
SYNCHRONIZE = 8, SYNCHRONIZE = 8,
//shut down the server PLAYER_NEW = 9,
SHUTDOWN = 9, PLAYER_DELETE = 10,
PLAYER_UPDATE = 11,
//Player movement, etc.
PLAYER_NEW = 10,
PLAYER_DELETE = 11,
PLAYER_UPDATE = 12,
}; };
//metadata on the packet itself //metadata on the packet itself
struct Metadata { struct Metadata {
Type type; Type type;
IPaddress srcAddress; IPaddress address;
int clientIndex;
}meta; }meta;
//information about the server //information about the server
@@ -77,28 +65,24 @@ union NetworkPacket {
//TODO: player count //TODO: player count
}serverInfo; }serverInfo;
//information about the client //information about a specific player
struct ClientInformation {
Metadata meta;
int index;
}clientInfo;
//information about a player
struct PlayerInformation { struct PlayerInformation {
Metadata meta; Metadata meta;
int clientIndex; int index;
int playerIndex;
char handle[PACKET_STRING_SIZE]; char handle[PACKET_STRING_SIZE];
char avatar[PACKET_STRING_SIZE]; char avatar[PACKET_STRING_SIZE];
Vector2 position; Vector2 position;
Vector2 motion; Vector2 motion;
//TODO Playerdata
}playerInfo; }playerInfo;
//defaults //zero the packet
NetworkPacket() { Packet() {
meta.type = Type::NONE; meta.type = Type::NONE;
meta.srcAddress = {0,0}; meta.address.host = 0;
} meta.address.port = 0;
meta.clientIndex = -1;
};
}; };
#pragma pack(pop) #pragma pack(pop)
@@ -23,8 +23,9 @@
#include <stdexcept> #include <stdexcept>
/* It might be more efficient to render to a different surface (like an Image) /* Note: This class can only take a raster font with 16*16 characters, and the
* rather than calling this function with all of it's '%' and '/'. * indevidual characters must have the same dimensions. Overall this class is too
* restrictive; I suggest using a 3rd party library.
*/ */
void RasterFont::DrawStringTo(std::string s, SDL_Surface* const dest, Sint16 x, Sint16 y) { void RasterFont::DrawStringTo(std::string s, SDL_Surface* const dest, Sint16 x, Sint16 y) {
@@ -40,21 +41,10 @@ void RasterFont::DrawStringTo(std::string s, SDL_Surface* const dest, Sint16 x,
} }
} }
/* Note: This class can only take a raster font with 16*16 characters, and the
* indevidual characters must have the same dimensions. Overall this class is too
* restrictive; I suggest using a 3rd party library.
*/
SDL_Surface* RasterFont::LoadSurface(std::string fname) {
image.LoadSurface(fname);
image.SetClipW(image.GetSurface()->w/16);
image.SetClipH(image.GetSurface()->h/16);
return image.GetSurface();
}
SDL_Surface* RasterFont::SetSurface(SDL_Surface* p) { SDL_Surface* RasterFont::SetSurface(SDL_Surface* p) {
image.SetSurface(p); if (image.SetSurface(p)) {
image.SetClipW(image.GetSurface()->w/16); image.SetClipW(image.GetSurface()->w/16);
image.SetClipH(image.GetSurface()->h/16); image.SetClipH(image.GetSurface()->h/16);
}
return image.GetSurface(); return image.GetSurface();
} }
@@ -24,29 +24,21 @@
#include "image.hpp" #include "image.hpp"
#include <string>
class RasterFont { class RasterFont {
public: public:
RasterFont() = default; RasterFont() = default;
RasterFont(RasterFont const& rhs) { *this = rhs; }
RasterFont(RasterFont&& rhs) { *this = std::move(rhs); }
RasterFont(std::string fname) { LoadSurface(fname); }
RasterFont(SDL_Surface* p) { SetSurface(p); } RasterFont(SDL_Surface* p) { SetSurface(p); }
~RasterFont() = default; ~RasterFont() = default;
RasterFont& operator=(RasterFont const& rhs) { image = rhs.image; }
RasterFont& operator=(RasterFont&& rhs) { image = std::move(rhs.image); }
void DrawStringTo(std::string, SDL_Surface* const, Sint16 x, Sint16 y); void DrawStringTo(std::string, SDL_Surface* const, Sint16 x, Sint16 y);
//Accessors and Mutators //Accessors and Mutators
SDL_Surface* LoadSurface(std::string);
SDL_Surface* SetSurface(SDL_Surface*); SDL_Surface* SetSurface(SDL_Surface*);
SDL_Surface* GetSurface() const { return image.GetSurface(); } SDL_Surface* GetSurface() const { return image.GetSurface(); }
void FreeSurface() { image.FreeSurface(); } Uint16 GetCharW() { return image.GetClipW(); }
Uint16 GetCharH() { return image.GetClipH(); }
Uint16 GetCharW() const { return image.GetClipW(); }
Uint16 GetCharH() const { return image.GetClipH(); }
private: private:
Image image; Image image;
}; };
+12 -17
View File
@@ -19,25 +19,20 @@
* 3. This notice may not be removed or altered from any source * 3. This notice may not be removed or altered from any source
* distribution. * distribution.
*/ */
#ifndef PLAYER_HPP_ #ifndef SINGLETON_HPP_
#define PLAYER_HPP_ #define SINGLETON_HPP_
#include "vector2.hpp" template<typename T>
class Singleton {
#include <string> public:
#include <map> static T* Get() {
return &instance;
/* Hold the player info. }
*/ private:
static T instance;
struct Player {
int clientIndex;
std::string handle;
std::string avatar;
Vector2 position;
Vector2 motion;
}; };
typedef std::map<int, Player> PlayerMap; template<typename T>
T Singleton<T>::instance;
#endif #endif
+14 -17
View File
@@ -19,26 +19,23 @@
* 3. This notice may not be removed or altered from any source * 3. This notice may not be removed or altered from any source
* distribution. * distribution.
*/ */
#include "tile.hpp" #include "sprite_sheet.hpp"
bool operator<(Tile const& lhs, Tile const& rhs) { void SpriteSheet::Update(double delta) {
//sort by depth -> y -> x if (delay && (ticks += delta) >= delay) {
if (lhs.depth == rhs.depth) { if (++currentFrame >= maxFrames) {
if (lhs.y == rhs.y) { currentFrame = 0;
return lhs.x < rhs.x;
} }
return lhs.y < rhs.y; ticks = 0;
} }
return lhs.depth < rhs.depth; image.SetClipX(currentFrame * image.GetClipW());
image.SetClipY(currentStrip * image.GetClipH());
} }
inline bool operator>(Tile const& lhs, Tile const& rhs) { SDL_Surface* SpriteSheet::SetSurface(SDL_Surface* const s, Uint16 w, Uint16 h) {
//wrap the other operator image.SetSurface(s);
return rhs < lhs; image.SetClip({0, 0, w, h});
} currentFrame = 0; maxFrames = image.GetSurface()->w / image.GetClipW();
currentStrip = 0; maxStrips = image.GetSurface()->h / image.GetClipH();
inline bool operator==(Tile const& lhs, Tile const& rhs) { delay = ticks = 0;
//comparisons work on the location ONLY
//this function is redundant as far as the std::set object is concerned
return (lhs.x == rhs.x) && (lhs.y == rhs.y) && (lhs.depth == rhs.depth);
} }
@@ -24,43 +24,39 @@
#include "image.hpp" #include "image.hpp"
#include "SDL/SDL.h"
class SpriteSheet { class SpriteSheet {
public: public:
SpriteSheet() = default; SpriteSheet() = default;
SpriteSheet(std::string fname, Uint16 xCellCount, Uint16 yCellCount) { LoadSurface(fname, xCellCount, yCellCount); } SpriteSheet(SDL_Surface* s, Uint16 w, Uint16 h) { SetSurface(s, w, h); }
SpriteSheet(SDL_Surface* surface, Uint16 xCellCount, Uint16 yCellCount) { SetSurface(surface, xCellCount, yCellCount); } ~SpriteSheet() = default;
~SpriteSheet() { FreeSurface(); };
void Update(double delta); void Update(double delta);
SDL_Surface* LoadSurface(std::string fname, Uint16 xCellCount, Uint16 yCellCount); SDL_Surface* SetSurface(SDL_Surface* const, Uint16 w, Uint16 h);
SDL_Surface* SetSurface(SDL_Surface* surface, Uint16 xCellCount, Uint16 yCellCount); SDL_Surface* GetSurface() const { return image.GetSurface(); }
SDL_Surface* GetSurface() { return image.GetSurface(); }
void FreeSurface();
void DrawTo(SDL_Surface* const dest, Sint16 x, Sint16 y) { image.DrawTo(dest, x, y); } void DrawTo(SDL_Surface* const dest, Sint16 x, Sint16 y) { image.DrawTo(dest, x, y); }
//accessors and mutators //Accessors and Mutators
Image* GetImage() { return &image; } //OO breaker double SetDelay(double i) { return delay = i; }
Uint16 SetXCount(Uint16);
Uint16 SetYCount(Uint16);
Uint16 SetXIndex(Uint16);
Uint16 SetYIndex(Uint16);
Uint16 GetXCount() const { return xCount; }
Uint16 GetYCount() const { return yCount; }
Uint16 GetXIndex() const { return xIndex; }
Uint16 GetYIndex() const { return yIndex; }
double SetDelay(double d);
double GetDelay() const { return delay; } double GetDelay() const { return delay; }
int SetCurrentFrame(int i) { return currentFrame = i; }
int SetCurrentStrip(int i) { return currentStrip = i; }
Uint16 GetFrameWidth() const { return image.GetClipW(); }
Uint16 GetFrameHeight() const { return image.GetClipH(); }
int GetCurrentFrame() const { return currentFrame; };
int GetCurrentStrip() const { return currentStrip; };
int GetMaxFrames() const { return maxFrames; }
int GetMaxStrips() const { return maxStrips; }
private: private:
Image image; Image image;
Uint16 xCount = 0, yCount = 0; //number of cells int currentFrame = 0, maxFrames = 0;
Uint16 xIndex = 0, yIndex = 0; //current cell being drawn int currentStrip = 0, maxStrips = 0;
double delay = 0.0, tick = 0.0; double delay = 0, ticks = 0;
}; };
#endif #endif
+81
View File
@@ -0,0 +1,81 @@
/* 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 "surface_manager.hpp"
#include <stdexcept>
SDL_Surface* SurfaceManager::Load(std::string key, std::string fname) {
MapType::iterator it = surfaceMap.find(key);
if (it != surfaceMap.end()) {
throw(std::runtime_error(std::string("Surface already loaded: ") + key + std::string(", ") + fname));
}
return LoadSurface(key, fname);
}
SDL_Surface* SurfaceManager::Reload(std::string key, std::string fname) {
MapType::iterator it = surfaceMap.find(key);
if (it != surfaceMap.end()) {
SDL_FreeSurface(it->second);
surfaceMap.erase(it);
}
return LoadSurface(key, fname);
}
SDL_Surface* SurfaceManager::Get(std::string key) {
MapType::iterator it = surfaceMap.find(key);
if (it == surfaceMap.end()) {
throw(std::runtime_error(std::string("Could not find key: ") + key));
}
return it->second;
}
SDL_Surface* SurfaceManager::Set(std::string key, SDL_Surface* ptr) {
MapType::iterator it = surfaceMap.find(key);
if (it != surfaceMap.end()) {
throw(std::runtime_error(std::string("Key already exists: ") + key));
}
return surfaceMap[key] = ptr;
}
void SurfaceManager::Free(std::string key) {
MapType::iterator it = surfaceMap.find(key);
if (it != surfaceMap.end()) {
SDL_FreeSurface(it->second);
surfaceMap.erase(it);
}
}
void SurfaceManager::FreeAll() {
for (auto it : surfaceMap) {
SDL_FreeSurface(it.second);
}
surfaceMap.clear();
}
SDL_Surface* SurfaceManager::LoadSurface(std::string key, std::string fname) {
SDL_Surface* ptr = SDL_LoadBMP(fname.c_str());
if (!ptr) {
throw(std::runtime_error(std::string("Failed to load file: ") + fname));
}
SDL_SetColorKey(ptr, SDL_SRCCOLORKEY, SDL_MapRGB(ptr->format, 255, 0, 255)); //default
return surfaceMap[key] = ptr;
}
@@ -19,33 +19,31 @@
* 3. This notice may not be removed or altered from any source * 3. This notice may not be removed or altered from any source
* distribution. * distribution.
*/ */
#ifndef TILESHEETMANAGER_HPP_ #ifndef SURFACEMANAGER_HPP_
#define TILESHEETMANAGER_HPP_ #define SURFACEMANAGER_HPP_
#include "tile_sheet.hpp" #include "SDL/SDL.h"
#include <map> #include <map>
#include <string> #include <string>
class TileSheetManager { class SurfaceManager {
public: public:
TileSheetManager() = default; SurfaceManager() = default;
~TileSheetManager() = default; ~SurfaceManager() noexcept { FreeAll(); }
TileSheet* LoadSheet(std::string fname, Uint16 w, Uint16 h); SDL_Surface* Load(std::string key, std::string fname);
TileSheet* GetSheet(std::string name); SDL_Surface* Reload(std::string key, std::string fname);
TileSheet* GetSheetByIndex(int tileIndex); SDL_Surface* Get(std::string key);
void UnloadSheet(std::string name); SDL_Surface* Set(std::string key, SDL_Surface* ptr);
void Free(std::string key);
void FreeAll();
void DrawTo(SDL_Surface* const, int x, int y, int tileIndex); SDL_Surface* operator[](std::string key) { return Get(key); };
int SetRangeEnd(int i) { return rangeEnd += i; }
int GetRangeEnd() const { return rangeEnd; }
std::map<std::string, TileSheet>* GetSheetMap() { return &sheetMap; }
private: private:
std::map<std::string, TileSheet> sheetMap; SDL_Surface* LoadSurface(std::string key, std::string fname);
int rangeEnd = 0; typedef std::map<std::string, SDL_Surface*> MapType;
MapType surfaceMap;
}; };
#endif #endif
@@ -32,9 +32,17 @@ public:
void Open(int port, int packSize); void Open(int port, int packSize);
void Close(); void Close();
//bind to a channel //bind to an available channel
int Bind(const char* ip, int port, int channel = -1); int Bind(const char* ip, int port) {
int Bind(IPaddress* add, int channel = -1); Bind(ip, port, -1);
}
int Bind(IPaddress* add) {
Bind(add, -1);
}
//bind to certain channel
int Bind(const char* ip, int port, int channel);
int Bind(IPaddress* add, int channel);
void Unbind(int channel); void Unbind(int channel);
IPaddress* GetIPAddress(int channel) { IPaddress* GetIPAddress(int channel) {
-43
View File
@@ -1,43 +0,0 @@
#config
INCLUDES+=. .. ../graphics
LIBS+=
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
#source
CXXSRC=$(wildcard *.cpp)
CSRC=$(wildcard *.c)
#objects
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
#output
OUTDIR=../..
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 $@ $<
$(OBJDIR)/%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean:
$(RM) *.o *.a *.exe
rebuild: clean all
-139
View File
@@ -1,139 +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 "menu_bar.hpp"
#include <stdexcept>
#include <sstream>
void MenuBar::DrawTo(SDL_Surface* const dest) {
for (auto& i : entries) {
i.DrawTo(dest);
}
}
void MenuBar::MouseMotion(SDL_MouseMotionEvent const& motion) {
for (auto& i : entries) {
i.MouseMotion(motion);
}
}
void MenuBar::MouseButtonDown(SDL_MouseButtonEvent const& button) {
for (auto& i : entries) {
i.MouseButtonDown(button);
}
}
void MenuBar::MouseButtonUp(SDL_MouseButtonEvent const& button, int* entry, int* butt) {
*entry = *butt = -1;
int ret = -1;
for (auto& i : entries) {
ret = i.MouseButtonUp(button);
if (ret != -1) {
*entry = (&i - entries.data());
*butt = ret;
}
}
}
void MenuBar::SetEntries(std::vector<std::vector<std::string>> info) {
if (!image || !font) {
throw(std::runtime_error("Surfaces not loaded into the menu bar"));
}
entries.clear();
for (int i = 0; i < info.size(); i++) {
//create the entry & the main button
entries.push_back(MenuBarEntry());
entries[i].mainButton.SetImage(image);
entries[i].mainButton.SetFont(font);
entries[i].mainButton.SetText(info[i][0]);
entries[i].mainButton.SetX(i * image->GetClipW());
entries[i].mainButton.SetY(0);
for (int j = 0; j < info[i].size()-1; j++) {
//create each drop button in this entry
entries[i].dropButtons.push_back(Button());
entries[i].dropButtons[j].SetImage(image);
entries[i].dropButtons[j].SetFont(font);
entries[i].dropButtons[j].SetText(info[i][j+1]);
entries[i].dropButtons[j].SetX(i * image->GetClipW());
entries[i].dropButtons[j].SetY((j+1) * image->GetClipH());
}
}
}
void MenuBar::MenuBarEntry::DrawTo(SDL_Surface* const dest) {
//only draw the dropButtons in the user has this menu open
mainButton.DrawTo(dest);
if (!open) {
return;
}
for (auto& i : dropButtons) {
i.DrawTo(dest);
}
}
void MenuBar::MenuBarEntry::MouseMotion(SDL_MouseMotionEvent const& motion) {
//open the menu
bool o = mainButton.MouseMotion(motion) == Button::State::PRESSED;
if (!(open |= o)) {
return;
}
for (auto& i : dropButtons) {
//dragging down the menu
o |= i.MouseMotion(motion) == Button::State::PRESSED;
}
open = o;
}
void MenuBar::MenuBarEntry::MouseButtonDown(SDL_MouseButtonEvent const& button) {
//open the menu
if (!(open = mainButton.MouseButtonDown(button) == Button::State::PRESSED)) {
return;
}
//update the others anyway
for (auto& i : dropButtons) {
i.MouseButtonDown(button);
}
}
int MenuBar::MenuBarEntry::MouseButtonUp(SDL_MouseButtonEvent const& button) {
int ret = -1;
mainButton.MouseButtonUp(button);
for (auto& i : dropButtons) {
//the user just released this button
if (i.GetState() != i.MouseButtonUp(button) && i.GetState() == Button::State::HOVER && open) {
//get this button's index
ret = (&i - dropButtons.data());
}
}
open = false;
return ret;
}
-91
View File
@@ -1,91 +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 MENUBAR_HPP_
#define MENUBAR_HPP_
#include "image.hpp"
#include "raster_font.hpp"
#include "button.hpp"
#include <string>
#include <vector>
/* I've redesigned this so that the contents of the menu bar can't change during run time.
* This is more restrictive but I'm focusing on getting this working first.
* The Image and Font pointers must be set before the text data is entered.
*
* This class needs a rewrite.
*/
class MenuBar {
public:
MenuBar() = default;
~MenuBar() = default;
//yet another draw function
void DrawTo(SDL_Surface* const dest);
//user inputs
void MouseMotion(SDL_MouseMotionEvent const&);
void MouseButtonDown(SDL_MouseButtonEvent const&);
void MouseButtonUp(SDL_MouseButtonEvent const&, int* entry, int* button);
//manage the entries & buttons
void SetEntries(std::vector<std::vector<std::string>> info);
void ClearEntries() { entries.clear(); }
//Accessors and mutators
Image* SetImage(Image* const ptr) { return image = ptr; }
Image* GetImage() { return image; }
RasterFont* SetFont(RasterFont* const ptr) { return font = ptr; }
RasterFont* GetFont() { return font; }
private:
class MenuBarEntry;
std::vector<MenuBarEntry> entries;
Image* image = nullptr;
RasterFont* font = nullptr;
};
class MenuBar::MenuBarEntry {
public:
MenuBarEntry() = default;
~MenuBarEntry() = default;
void DrawTo(SDL_Surface* const dest);
void MouseMotion(SDL_MouseMotionEvent const&);
void MouseButtonDown(SDL_MouseButtonEvent const&);
int MouseButtonUp(SDL_MouseButtonEvent const&);
private:
Button mainButton;
std::vector<Button> dropButtons;
bool open = false;
friend class MenuBar;
};
#endif
-59
View File
@@ -1,59 +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 "utility.hpp"
#include <algorithm>
int snapToBase(int base, int x) {
//snap to a grid
if (x < 0) {
x++;
return x - x % base - base;
}
return x - x % base;
}
std::string truncatePath(std::string pathname) {
return std::string(
std::find_if(
pathname.rbegin(),
pathname.rend(),
[](char ch) -> bool {
//windows only
return ch == '/' || ch == '\\';
// //unix only
// return ch == '/';
}).base(),
pathname.end());
}
std::string to_string_custom(int i) {
char buffer[20];
snprintf(buffer, 20, "%d", i);
return std::string(buffer);
}
int to_integer_custom(std::string s) {
int ret = 0;
sscanf(s.c_str(), "%d", &ret);
return ret;
}
-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 UTILITY_HPP_
#define UTILITY_HPP_
#include <string>
int snapToBase(int base, int x);
std::string truncatePath(std::string pathname);
//fixing known bugs in g++
std::string to_string_custom(int i);
int to_integer_custom(std::string);
//wow
template<typename ContainerT, typename PredicateT>
void erase_if(ContainerT& items, const PredicateT& predicate) {
for(auto it = items.begin(); it != items.end(); /* empty */) {
if(predicate(*it)) {
it = items.erase(it);
}
else {
++it;
}
}
};
#endif
+3 -8
View File
@@ -27,13 +27,8 @@
class Vector2 { class Vector2 {
public: public:
double x, y; double x = 0, y = 0;
//This is explicitly a POD
Vector2() = default; Vector2() = default;
Vector2(double i, double j): x(i), y(j) {};
~Vector2() = default;
Vector2& operator=(Vector2 const&) = default;
double Length() const { double Length() const {
return sqrt(x*x+y*y); return sqrt(x*x+y*y);
@@ -94,7 +89,7 @@ public:
bool operator==(Vector2 v) { return (x == v.x && y == v.y); } bool operator==(Vector2 v) { return (x == v.x && y == v.y); }
bool operator!=(Vector2 v) { return (x != v.x || y != v.y); } bool operator!=(Vector2 v) { return (x != v.x || y != v.y); }
//member templates (curry the above operators) //member templates
template<typename T> Vector2 operator+=(T t) { return *this = *this + t; } template<typename T> Vector2 operator+=(T t) { return *this = *this + t; }
template<typename T> Vector2 operator-=(T t) { return *this = *this - t; } template<typename T> Vector2 operator-=(T t) { return *this = *this - t; }
template<typename T> Vector2 operator*=(T t) { return *this = *this * t; } template<typename T> Vector2 operator*=(T t) { return *this = *this * t; }
@@ -103,7 +98,7 @@ public:
template<typename T> bool operator!=(T t) { return (x != t || y != t); } template<typename T> bool operator!=(T t) { return (x != t || y != t); }
}; };
//non-member templates (flip the order) //non-member templates
template<typename T> Vector2 operator+(T t, Vector2 v) { return v + t; } template<typename T> Vector2 operator+(T t, Vector2 v) { return v + t; }
template<typename T> Vector2 operator-(T t, Vector2 v) { return v - t; } template<typename T> Vector2 operator-(T t, Vector2 v) { return v - t; }
template<typename T> Vector2 operator*(T t, Vector2 v) { return v * t; } template<typename T> Vector2 operator*(T t, Vector2 v) { return v * t; }
-139
View File
@@ -1,139 +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 "base_scene.hpp"
#include <stdexcept>
//-------------------------
//Static declarations
//-------------------------
SDL_Surface* BaseScene::screen = nullptr;
//-------------------------
//Public access members
//-------------------------
BaseScene::BaseScene() {
//
}
BaseScene::~BaseScene() {
//
}
//-------------------------
//Program control
//-------------------------
SDL_Surface* BaseScene::SetScreen(int w, int h, int bpp, Uint32 flags) {
if (!bpp) {
bpp = SDL_GetVideoInfo()->vfmt->BitsPerPixel;
}
screen = SDL_SetVideoMode(w, h, bpp, flags);
if (!screen) {
throw(std::runtime_error("Failed to create the screen surface"));
}
return screen;
}
SDL_Surface* BaseScene::GetScreen() {
return screen;
}
SceneList BaseScene::SetNextScene(SceneList sceneIndex) {
return nextScene = sceneIndex;
}
SceneList BaseScene::GetNextScene() const {
return nextScene;
}
//-------------------------
//Frame loop
//-------------------------
void BaseScene::RunFrame(double delta) {
FrameStart();
HandleEvents();
Update(delta);
FrameEnd();
}
void BaseScene::RenderFrame() {
SDL_FillRect(screen, 0, 0);
Render(screen);
SDL_Flip(screen);
}
//-------------------------
//Event handlers
//-------------------------
void BaseScene::HandleEvents() {
SDL_Event event;
while(SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_QUIT:
QuitEvent();
break;
case SDL_VIDEORESIZE:
SetScreen(event.resize.w, event.resize.h, 0, screen->flags);
break;
case SDL_MOUSEMOTION:
MouseMotion(event.motion);
break;
case SDL_MOUSEBUTTONDOWN:
MouseButtonDown(event.button);
break;
case SDL_MOUSEBUTTONUP:
MouseButtonUp(event.button);
break;
case SDL_KEYDOWN:
KeyDown(event.key);
break;
case SDL_KEYUP:
KeyUp(event.key);
break;
#ifdef USE_EVENT_JOYSTICK
//TODO: joystick/gamepad support
#endif
#ifdef USE_EVENT_UNKNOWN
default:
UnknownEvent(event);
break;
#endif
}//switch
}//while
}
-130
View File
@@ -1,130 +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 EditorApplications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "editor_application.hpp"
#include <stdexcept>
#include <chrono>
//-------------------------
//Static declarations
//-------------------------
EditorApplication EditorApplication::instance;
//-------------------------
//Scene headers
//-------------------------
//Add the custom scene headers here
#include "editor_scene.hpp"
#include "testificate_scene.hpp"
//-------------------------
//Public access members
//-------------------------
EditorApplication::EditorApplication() {
//
}
EditorApplication::~EditorApplication() {
//
}
void EditorApplication::Init() {
config.Load("rsc\\config.cfg");
if (SDL_Init(SDL_INIT_VIDEO))
throw(std::runtime_error("Failed to initialize SDL"));
BaseScene::SetScreen(config.Int("screen.w"), config.Int("screen.h"));
}
void EditorApplication::Proc() {
LoadScene(SceneList::FIRST);
//prepare the time system
typedef std::chrono::steady_clock Clock;
Clock::duration delta(16 * Clock::duration::period::den / std::milli::den);
Clock::time_point simTime = Clock::now();
Clock::time_point realTime;
//The main loop
while(activeScene->GetNextScene() != SceneList::QUIT) {
//switch scenes when necessary
if (activeScene->GetNextScene() != SceneList::CONTINUE) {
LoadScene(activeScene->GetNextScene());
continue;
}
//update the current time
realTime = Clock::now();
//simulate game time
while (simTime < realTime) {
//call each user defined function
activeScene->RunFrame(double(delta.count()) / Clock::duration::period::den);
simTime += delta;
}
//draw the game to the screen
activeScene->RenderFrame();
//give the computer a break
SDL_Delay(10);
}
UnloadScene();
}
void EditorApplication::Quit() {
SDL_Quit();
}
//-------------------------
//Private access members
//-------------------------
void EditorApplication::LoadScene(SceneList sceneIndex) {
UnloadScene();
switch(sceneIndex) {
//add scene creation calls here
case SceneList::FIRST:
case SceneList::EDITORSCENE:
activeScene = new EditorScene(&config);
break;
case SceneList::TESTIFICATESCENE:
activeScene = new TestificateScene(&config);
break;
default:
throw(std::logic_error("Failed to recognize the scene index"));
}
}
void EditorApplication::UnloadScene() {
delete activeScene;
activeScene = nullptr;
}
-53
View File
@@ -1,53 +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 EDITORAPPLICATION_HPP_
#define EDITORAPPLICATION_HPP_
#include "scene_list.hpp"
#include "base_scene.hpp"
#include "config_utility.hpp"
class EditorApplication {
private:
EditorApplication();
~EditorApplication();
static EditorApplication instance;
public:
static EditorApplication* GetInstance() { return &instance; }
void Init();
void Proc();
void Quit();
private:
//Private access members
void LoadScene(SceneList sceneIndex);
void UnloadScene();
//globals
ConfigUtility config;
BaseScene* activeScene = nullptr;
};
#endif
-282
View File
@@ -1,282 +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 "editor_scene.hpp"
#include "utility.hpp"
#include <cstdio>
#include <iostream>
#include <stdexcept>
using namespace std;
//-------------------------
//Public access members
//-------------------------
EditorScene::EditorScene(ConfigUtility* const arg1):
config(*arg1)
{
//create the debugging "window"
debugInfo.CreateSurface(256, 256);
//setup the utility objects
font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp");
buttonImage.LoadSurface(config["dir.interface"] + "button_menu.bmp");
buttonImage.SetClipH(buttonImage.GetClipH()/3);
//setup the menu bar
menuBar.SetFont(&font);
menuBar.SetImage(&buttonImage);
menuBar.SetEntries({
{"File", "-New", "-Open", "-Save", "-Save As...", "-Close", "Exit"},
{"Edit", "-Set Tile", "-Load Sheet", "-Delete Sheet", "-Metadata", "-Run Script"},
{"Debugging", "Debug On", "Debug Off", "Toggle Debug", "Testificate"}
});
//setup the pager
pager.SetOnNew([](Region* const ptr){
printf("New Region: %d, %d\n", ptr->GetX(), ptr->GetY());
});
pager.SetOnDelete([](Region* const ptr){
printf("Delete Region: %d, %d\n", ptr->GetX(), ptr->GetY());
});
//Set a resonable size for the regions
pager.SetWidth(32*4);
pager.SetHeight(32*4);
sheetMgr.LoadSheet(config["dir.tilesets"] + "terrain.bmp", 32, 32);
}
EditorScene::~EditorScene() {
//
}
//-------------------------
//Frame loop
//-------------------------
void EditorScene::FrameStart() {
//
}
void EditorScene::Update(double delta) {
pager.Prune(camera.x, camera.y, camera.x + GetScreen()->w, camera.y + GetScreen()->h);
}
void EditorScene::FrameEnd() {
//
}
void EditorScene::Render(SDL_Surface* const screen) {
//draw the map
pager.DrawTo(screen, &sheetMgr, camera.x, camera.y);
//draw a big bar across the top
buttonImage.SetClipY(0);
for (int i = 0; i < screen->w; i += buttonImage.GetClipW()) {
buttonImage.DrawTo(screen, i, 0);
}
//draw the menu bar
menuBar.DrawTo(screen);
//draw some debugging info
if (debugOpen) {
SDL_FillRect(debugInfo.GetSurface(), 0, 0);
DrawToDebugInfo(string("camera.x: ") + to_string_custom(camera.x), 0);
DrawToDebugInfo(string("camera.y: ") + to_string_custom(camera.y), 1);
debugInfo.DrawTo(screen, screen->w - debugInfo.GetClipW(), buttonImage.GetClipH());
}
}
void EditorScene::DrawToDebugInfo(std::string str, int line) {
//draw the debug info on the right
font.DrawStringTo(
str,
debugInfo.GetSurface(),
debugInfo.GetClipW() - str.size() * font.GetCharW(),
font.GetCharH() * line
);
}
//-------------------------
//Event handlers
//-------------------------
void EditorScene::MouseMotion(SDL_MouseMotionEvent const& motion) {
menuBar.MouseMotion(motion);
if (motion.state & SDL_BUTTON_LMASK && motion.y >= buttonImage.GetClipH()) {
Region* regionPtr = pager.GetRegion(
snapToBase(pager.GetWidth(), motion.x + camera.x),
snapToBase(pager.GetHeight(), motion.y + camera.y)
);
TileSheet* sheetPtr = sheetMgr.GetSheetByIndex(tileCounter);
regionPtr->NewTileA({
snapToBase(sheetPtr->GetTileW(), motion.x + camera.x), //x
snapToBase(sheetPtr->GetTileH(), motion.y + camera.y), //y
0, //depth
sheetPtr->GetTileW(), //width
sheetPtr->GetTileH(), //height
tileCounter++ //value
});
}
if (motion.state & SDL_BUTTON_RMASK) {
camera.x -= motion.xrel;
camera.y -= motion.yrel;
}
}
void EditorScene::MouseButtonDown(SDL_MouseButtonEvent const& button) {
menuBar.MouseButtonDown(button);
if (button.button == SDL_BUTTON_LEFT && button.y >= buttonImage.GetClipH()) {
Region* regionPtr = pager.GetRegion(
snapToBase(pager.GetWidth(), button.x + camera.x),
snapToBase(pager.GetHeight(), button.y + camera.y)
);
TileSheet* sheetPtr = sheetMgr.GetSheetByIndex(tileCounter);
regionPtr->NewTileA({
snapToBase(sheetPtr->GetTileW(), button.x + camera.x), //x
snapToBase(sheetPtr->GetTileH(), button.y + camera.y), //y
0, //depth
sheetPtr->GetTileW(), //width
sheetPtr->GetTileH(), //height
tileCounter++ //value
});
}
}
void EditorScene::MouseButtonUp(SDL_MouseButtonEvent const& button) {
int entry, drop;
menuBar.MouseButtonUp(button, &entry, &drop);
//manage input from the menu bar
switch(entry) {
case 0: //File
switch(drop) {
case 0:
//TODO: NEW
break;
case 1:
//TODO: OPEN
break;
case 2:
//TODO: SAVE
break;
case 3:
//TODO: SAVE AS
break;
case 4:
//TODO: CLOSE
break;
case 5: {
//Quit
SDL_Event e;
e.type = SDL_QUIT;
SDL_PushEvent(&e);
}
break;
}
break;
case 1: //Edit
switch(drop) {
case 0:
//TODO: SET TILE
break;
case 1:
//TODO: LOAD SHEET
break;
case 2:
//TODO: DELETE SHEET
break;
case 3:
//TODO: METADATA
break;
case 4:
//TODO: RUN SCRIPT
break;
}
break;
case 2: //Debug
switch(drop) {
case 0:
debugOpen = true;
break;
case 1:
debugOpen = false;
break;
case 2:
debugOpen = !debugOpen;
break;
case 3:
SetNextScene(SceneList::TESTIFICATESCENE);
break;
}
break;
}
}
void EditorScene::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE:
QuitEvent();
break;
case SDLK_SPACE:
camera.x = 0;
camera.y = 0;
break;
case SDLK_TAB:
debugOpen = !debugOpen;
break;
}
}
void EditorScene::KeyUp(SDL_KeyboardEvent const& key) {
//
}
-80
View File
@@ -1,80 +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 EDITORSCENE_HPP_
#define EDITORSCENE_HPP_
#include "base_scene.hpp"
#include "region_pager.hpp"
#include "tile_sheet_manager.hpp"
#include "config_utility.hpp"
#include "image.hpp"
#include "raster_font.hpp"
#include "menu_bar.hpp"
//#include "map_loader.hpp"
class EditorScene : public BaseScene {
public:
//Public access members
EditorScene(ConfigUtility* const);
~EditorScene();
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&);
//globals
ConfigUtility& config;
//debugging tools
void DrawToDebugInfo(std::string, int line);
Image debugInfo;
bool debugOpen = true;
RegionPager pager;
TileSheetManager sheetMgr;
RasterFont font;
Image buttonImage;
MenuBar menuBar;
struct {
int x = 0, y = 0;
} camera;
int tileCounter = 0;
};
#endif
-43
View File
@@ -1,43 +0,0 @@
#config
INCLUDES+=../common ../common/graphics ../common/map ../common/ui
LIBS+=../libcommon.a -lmingw32 -lSDLmain -lSDL
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
#source
CXXSRC=$(wildcard *.cpp)
CSRC=$(wildcard *.c)
#objects
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
#output
OUTDIR=../out
OUT=$(addprefix $(OUTDIR)/,editor)
#targets
all: $(OBJ) $(OUT)
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS)
$(OBJ): | $(OBJDIR)
$(OUT): | $(OUTDIR)
$(OBJDIR):
mkdir $(OBJDIR)
$(OUTDIR):
mkdir $(OUTDIR)
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
$(OBJDIR)/%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean:
$(RM) *.o *.a *.exe
rebuild: clean all
-107
View File
@@ -1,107 +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 "testificate_scene.hpp"
#include <iostream>
using std::cout;
using std::endl;
//-------------------------
//Public access members
//-------------------------
TestificateScene::TestificateScene(ConfigUtility* const arg1):
config(*arg1)
{
sheetMgr.LoadSheet(config["dir.tilesets"] + "grass.bmp", 32, 32);
sheetMgr.LoadSheet(config["dir.tilesets"] + "longgrass.bmp", 32, 32);
sheetMgr.LoadSheet(config["dir.tilesets"] + "sand.bmp", 32, 32);
sheetMgr.LoadSheet(config["dir.tilesets"] + "dirt.bmp", 32, 32);
sheetMgr.LoadSheet(config["dir.tilesets"] + "water.bmp", 32, 32);
cout << "Range End: " << sheetMgr.GetRangeEnd() << endl;
pager.SetWidth(128);
pager.SetHeight(128);
pager.GetRegion(0, 0)->NewTileR({0, 0, 0, 32, 32, 0});
}
TestificateScene::~TestificateScene() {
//
}
//-------------------------
//Frame loop
//-------------------------
void TestificateScene::FrameStart() {
//
}
void TestificateScene::Update(double delta) {
//
}
void TestificateScene::FrameEnd() {
//
}
void TestificateScene::Render(SDL_Surface* const screen) {
//dump all tile graphics to the screen
for (int i = 0; i < sheetMgr.GetRangeEnd(); i++) {
sheetMgr.DrawTo(screen, i * 32 % screen->w, i * 32 / screen->w * 32, i);
}
// pager.DrawTo(screen, &sheetMgr, 0, 0);
}
//-------------------------
//Event handlers
//-------------------------
void TestificateScene::MouseMotion(SDL_MouseMotionEvent const& motion) {
//
}
void TestificateScene::MouseButtonDown(SDL_MouseButtonEvent const& button) {
//
}
void TestificateScene::MouseButtonUp(SDL_MouseButtonEvent const& button) {
//
}
void TestificateScene::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE:
// QuitEvent();
SetNextScene(SceneList::EDITORSCENE);
break;
}
}
void TestificateScene::KeyUp(SDL_KeyboardEvent const& key) {
//
}
-59
View File
@@ -1,59 +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 TESTIFICATESCENE_HPP_
#define TESTIFICATESCENE_HPP_
#include "base_scene.hpp"
#include "config_utility.hpp"
#include "tile_Sheet_manager.hpp"
#include "region_pager.hpp"
class TestificateScene : public BaseScene {
public:
//Public access members
TestificateScene(ConfigUtility* const);
~TestificateScene();
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&);
//globals
ConfigUtility& config;
//members
TileSheetManager sheetMgr;
RegionPager pager;
};
#endif
+6 -12
View File
@@ -1,20 +1,14 @@
#for use on Windows: LIBDIR=lib
#MKDIR=mkdir
#RM=del /y
CXXFLAGS+=-static-libgcc -static-libstdc++
CFLAGS+=-static-libgcc
export
OUTDIR=out OUTDIR=out
all: $(OUTDIR) all: $(LIBDIR) $(OUTDIR)
$(MAKE) -C common $(MAKE) -C common
$(MAKE) -C server $(MAKE) -C server
$(MAKE) -C client $(MAKE) -C client
$(MAKE) -C editor $(MAKE) -C test
$(LIBDIR):
mkdir $(LIBDIR)
$(OUTDIR): $(OUTDIR):
mkdir $(OUTDIR) mkdir $(OUTDIR)
+11 -15
View File
@@ -1,24 +1,20 @@
#configuration of the programs #configuration of the programs
server.host = 255.255.255.255 server.host = 127.0.0.1
server.port = 21795 server.port = 1991
server.name = local server.name = foobar
server.dbname = database.db
screen.w = 800 screen.w = 800
screen.h = 600 screen.h = 600
screen.f = false screen.f = false
#directories #directories
dir.fonts = rsc/graphics/fonts/ fonts = rsc/graphics/fonts
dir.logos = rsc/graphics/logos/ logos = rsc/graphics/logos
dir.sprites = rsc/graphics/sprites/ sprites = rsc/graphics/sprites
dir.tilesets = rsc/graphics/tilesets/ tilesets = rsc/graphics/tilesets
dir.interface = rsc/graphics/interface/ interface = rsc/graphics/interface
dir.scripts = rsc/scripts/
#player options
player.handle = username
player.avatar = elliot2.bmp
#debugging #debugging
debug = true
avatar = elliot
handle = UserName
Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

View File
View File
-73
View File
@@ -1,73 +0,0 @@
-------------------------
--Server
-------------------------
CREATE TABLE IF NOT EXISTS UserAccounts (
userAccountID INTEGER PRIMARY KEY AUTOINCREMENT,
username varchar(30) UNIQUE,
password varchar(30),
blacklisted BIT DEFAULT 0,
whitelisted BIT DEFAULT 1
);
-------------------------
--Items
-------------------------
CREATE TABLE IF NOT EXISTS GlobalItemList (
globalItemListID INTEGER PRIMARY KEY AUTOINCREMENT,
itemName varchar(30) UNIQUE,
itemImage varchar(30),
type varchar(15), --{'mundane', 'consumable', 'equipment'}
maxStackSize INTEGER, --{1-max; 0 for non-stackable}
maxUniqueCopies INTEGER --{1-max; 0 for unlimited}
);
CREATE TABLE IF NOT EXISTS MundaneItems (
mundaneItemID INTEGER PRIMARY KEY AUTOINCREMENT,
globalItemListID INTEGER REFERENCES GlobalItemList(globalItemListID)
--holds whatever
);
CREATE TABLE IF NOT EXISTS Consumables (
consumableID INTEGER PRIMARY KEY AUTOINCREMENT,
globalItemListID INTEGER REFERENCES GlobalItemList(globalItemListID)
--holds all consumable items info (food, potions, etc.)
);
CREATE TABLE IF NOT EXISTS Equipment (
equipmentID INTEGER PRIMARY KEY AUTOINCREMENT,
globalItemListID INTEGER REFERENCES GlobalItemList(globalItemListID)
--hold all equipment info
);
-------------------------
--Players
-------------------------
CREATE TABLE IF NOT EXISTS PlayerCharacters (
playerCharacterID INTEGER PRIMARY KEY AUTOINCREMENT,
name varchar(30) UNIQUE,
--stats
currentLevel INTEGER DEFAULT 0,
currentExperience INTEGER DEFAULT 0,
maxHealth INTEGER DEFAULT 0,
maxMana INTEGER DEFAULT 0,
currentHealth INTEGER DEFAULT 0,
currentMana INTEGER DEFAULT 0,
attack INTEGER DEFAULT 0,
defence INTEGER DEFAULT 0,
--etc.
--equipment
weapon INTEGER REFERENCES Equipment(equipmentID),
helmet INTEGER REFERENCES Equipment(equipmentID),
armour INTEGER REFERENCES Equipment(equipmentID)
--etc.
);
CREATE TABLE IF NOT EXISTS PlayerInventoryItems (
characterID INTEGER REFERENCES PlayerCharacters(characterID),
globalItemListID INTEGER REFERENCES GlobalItemList(globalItemListID)
);
+8 -6
View File
@@ -21,25 +21,27 @@
*/ */
#include "server_application.hpp" #include "server_application.hpp"
#include "SDL/SDL.h"
#include <stdexcept> #include <stdexcept>
#include <iostream> #include <iostream>
using namespace std; using namespace std;
int main(int argc, char** argv) { int main(int, char**) {
#ifdef DEBUG
cout << "Beginning server" << endl; cout << "Beginning server" << endl;
#endif
try { try {
ServerApplication app; ServerApplication app;
app.Init(argc, argv); app.Init();
app.Loop(); app.Proc();
app.Quit(); app.Quit();
} }
catch(exception& e) { catch(exception& e) {
cerr << "Fatal error: " << e.what() << endl; cerr << "Fatal error: " << e.what() << endl;
return 1; return 1;
} }
#ifdef DEBUG
cout << "Clean exit" << endl; cout << "Clean exit" << endl;
#endif
return 0; return 0;
} }
+6 -11
View File
@@ -1,17 +1,15 @@
#config #config
INCLUDES+=. ../common ../common/map ../common/network LOCALLIBS=../lib/libCommon.a
LIBS+=../libcommon.a -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL -llua -lsqlite3 LIB=$(LOCALLIBS) -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL
INCLUDES=../common
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES)) CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
#source #source
CXXSRC=$(wildcard *.cpp) SRC=$(wildcard *.cpp)
CSRC=$(wildcard *.c)
#objects #objects
OBJDIR=obj OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o)) OBJ=$(addprefix $(OBJDIR)/,$(SRC:.cpp=.o))
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
#output #output
OUTDIR=../out OUTDIR=../out
@@ -19,7 +17,7 @@ OUT=$(addprefix $(OUTDIR)/,server)
#targets #targets
all: $(OBJ) $(OUT) all: $(OBJ) $(OUT)
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS) $(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIB)
$(OBJ): | $(OBJDIR) $(OBJ): | $(OBJDIR)
@@ -34,9 +32,6 @@ $(OUTDIR):
$(OBJDIR)/%.o: %.cpp $(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $< $(CXX) $(CXXFLAGS) -c -o $@ $<
$(OBJDIR)/%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean: clean:
$(RM) *.o *.a *.exe $(RM) *.o *.a *.exe
+221 -203
View File
@@ -21,17 +21,24 @@
*/ */
#include "server_application.hpp" #include "server_application.hpp"
#include "utility.hpp"
#include <stdexcept> #include <stdexcept>
#include <iostream> #include <iostream>
#include <string> #include <chrono>
#include <fstream>
using namespace std; using namespace std;
//------------------------- //-------------------------
//Define the ServerApplication //Quick and dirty
//-------------------------
static std::string itos(int i) {
char buffer[20];
snprintf(buffer, 20, "%d", i);
return std::string(buffer);
}
//-------------------------
//Public access members
//------------------------- //-------------------------
ServerApplication::ServerApplication() { ServerApplication::ServerApplication() {
@@ -42,259 +49,270 @@ ServerApplication::~ServerApplication() {
// //
} }
void ServerApplication::Init(int argc, char** argv) { /* ServerApplication::Init()
//TODO: proper command line option parsing * 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 initialized here.
* The ConfigUtility's call to Load() also ensures that the "rsc\" folder is in the directory. It's easy to forget it.
*/
//load config void ServerApplication::Init() {
config.Load("rsc\\config.cfg"); //load the config file
try {
//Init SDL configUtil->Load("rsc/config.cfg");
if (SDL_Init(0)) { }
throw(runtime_error("Failed to initialize SDL")); catch(std::runtime_error& e) {
std::string s = e.what();
s += "; Ensure that the \"rsc\" directory is present";
throw(std::runtime_error(s));
} }
cout << "initialized SDL" << endl;
//Init SDL_net //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()) { if (SDLNet_Init()) {
throw(runtime_error("Failed to init SDL_net")); throw(runtime_error("Failed to initialize SDL_net"));
} }
network.Open(config.Int("server.port"), sizeof(NetworkPacket));
cout << "initialized SDL_net" << endl;
//Init SQL //initiate the remaining singletons
string dbname = (config["server.dbname"].size()) ? config["server.dbname"] : std::string(argv[0]) + ".db"; //fancy and unnecessary netUtil->Open(configUtil->Int("server.port"), sizeof(Packet));
int ret = sqlite3_open_v2(dbname.c_str(), &database, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_FULLMUTEX, nullptr);
if (ret != SQLITE_OK || !database) {
throw(runtime_error("Failed to open the server database"));
}
cout << "initialized SQL" << endl;
cout << "Database filename: " << dbname << endl;
//TODO: move this into a function? //create the threads
//Run setup scripts beginQueueThread();
ifstream is("rsc\\scripts\\setup_server.sql");
if (!is.is_open()) { //output the server information
throw(runtime_error("Failed to run database setup script")); cout << configUtil->String("server.name") << endl;
} cout << "Open on port " << configUtil->String("server.port") << endl;
string script;
getline(is, script, '\0'); //disable this for debugging
is.close(); running = true;
sqlite3_exec(database, script.c_str(), nullptr, nullptr, nullptr);
} }
void ServerApplication::Loop() { void ServerApplication::Proc() {
NetworkPacket packet; typedef chrono::high_resolution_clock Clock;
Clock::time_point lastTick = Clock::now();
Clock::duration delta;
while(running) { while(running) {
//suck in the waiting packets & process them
try { try {
while(network.Receive()) { //process all packets on the network queue
memcpy(&packet, network.GetInData(), sizeof(NetworkPacket)); while(HandlePacket(popNetworkPacket()));
packet.meta.srcAddress = network.GetInPacket()->address;
HandlePacket(packet);
}
} }
catch(exception& e) { catch(exception& e) {
//handle any errors
cerr << "Network Error: " << e.what() << endl; cerr << "Network Error: " << e.what() << endl;
continue;
} }
//give the computer a break //get the time since last update
delta = Clock::now() - lastTick;
lastTick = Clock::now();
//update the world
UpdateWorld(double(delta.count()) / Clock::duration::period::den);
//give the machine a break
SDL_Delay(10); SDL_Delay(10);
} }
} }
void ServerApplication::Quit() { void ServerApplication::Quit() {
//members //close the threads
network.Close(); endQueueThread();
//APIs //clean up the singletons
sqlite3_close_v2(database); netUtil->Close();
//deinitialize the APIs
SDLNet_Quit(); SDLNet_Quit();
SDL_Quit();
} }
void ServerApplication::HandlePacket(NetworkPacket packet) { //-------------------------
switch(packet.meta.type) { //Game loop
case NetworkPacket::Type::BROADCAST_REQUEST: //-------------------------
HandleBroadcastRequest(packet);
break;
case NetworkPacket::Type::JOIN_REQUEST: void ServerApplication::UpdateWorld(double delta) {
HandleJoinRequest(packet); //the recalc here each loop is a stopgap, see issue #9 for details
break; for (auto& it : players) {
if (it.second.motion.x != 0 && it.second.motion.y != 0) {
constexpr double d = 1.0/sqrt(2);
it.second.position += it.second.motion * delta * d;
}
else {
it.second.position += it.second.motion * delta;
}
}
}
case NetworkPacket::Type::DISCONNECT: //-------------------------
HandleDisconnect(packet); //Network loop
break; //-------------------------
case NetworkPacket::Type::SYNCHRONIZE: int ServerApplication::HandlePacket(Packet p) {
HandleSynchronize(packet); switch(p.meta.type) {
case Packet::Type::NONE:
//DO NOTHING
return 0;
break; break;
case Packet::Type::PING:
case NetworkPacket::Type::SHUTDOWN: //quick pong
HandleShutdown(packet); p.meta.type = Packet::Type::PONG;
netUtil->Send(&p.meta.address, &p, sizeof(Packet));
break; break;
case Packet::Type::PONG:
case NetworkPacket::Type::PLAYER_NEW: //
HandlePlayerNew(packet);
break; break;
case Packet::Type::BROADCAST_REQUEST:
case NetworkPacket::Type::PLAYER_DELETE: HandleBroadcast(p);
HandlePlayerDelete(packet);
break; break;
// case PacketType::BROADCAST_RESPONSE:
case NetworkPacket::Type::PLAYER_UPDATE: // //
HandlePlayerUpdate(packet); // break;
case Packet::Type::JOIN_REQUEST:
HandleConnection(p);
break;
// case PacketType::JOIN_RESPONSE:
// //
// break;
case Packet::Type::DISCONNECT:
HandleDisconnection(p);
break;
case Packet::Type::SYNCHRONIZE:
SynchronizeEverything(p);
break;
case Packet::Type::PLAYER_NEW:
AddPlayer(p);
RelayPacket(p);
break;
case Packet::Type::PLAYER_DELETE:
RemovePlayer(p);
RelayPacket(p);
break;
case Packet::Type::PLAYER_UPDATE:
UpdatePlayer(p);
RelayPacket(p);
break; break;
//handle errors
default: default:
throw(runtime_error("Unknown NetworkPacket::Type encountered")); throw(runtime_error("Failed to recognize the packet type: " + itos(int(p.meta.type))));
break; }
return 1;
}
void ServerApplication::RelayPacket(Packet& p) {
//pump this packet to all clients
for (auto& it : clients) {
netUtil->Send(&it.second.address, &p, sizeof(Packet));
} }
} }
void ServerApplication::HandleBroadcastRequest(NetworkPacket packet) { void ServerApplication::SynchronizeEverything(Packet& sync) {
//send back the server's name //send all known data to this client
packet.meta.type = NetworkPacket::Type::BROADCAST_RESPONSE; //TODO multithreading?
snprintf(packet.serverInfo.name, PACKET_STRING_SIZE, "%s", config["server.name"].c_str());
network.Send(&packet.meta.srcAddress, &packet, sizeof(NetworkPacket));
}
void ServerApplication::HandleJoinRequest(NetworkPacket packet) { //all players
//TODO: prevent duplicate logins from the same address? Packet p;
p.meta.type = Packet::Type::PLAYER_UPDATE;
for (auto& it : players) {
p.meta.clientIndex = it.second.clientIndex;
//create the new client, filling it with the correct info p.playerInfo.index = it.second.index;
Client newClient; snprintf(p.playerInfo.handle, PACKET_STRING_SIZE, "%s", it.second.handle.c_str());
newClient.address = packet.meta.srcAddress; snprintf(p.playerInfo.avatar, PACKET_STRING_SIZE, "%s", it.second.avatar.c_str());
p.playerInfo.position = it.second.position;
p.playerInfo.motion = it.second.motion;
//push the new client netUtil->Send(&clients[sync.meta.clientIndex].address, &p, sizeof(Packet));
clientMap[clientCounter] = newClient;
//send the client their info
packet.meta.type = NetworkPacket::Type::JOIN_RESPONSE;
packet.clientInfo.index = clientCounter;
network.Send(&newClient.address, &packet, sizeof(NetworkPacket));
//finished this routine
clientCounter++;
cout << "connect, total: " << clientMap.size() << endl;
}
void ServerApplication::HandleDisconnect(NetworkPacket packet) {
//disconnect the specified client
network.Send(&clientMap[packet.clientInfo.index].address, &packet, sizeof(NetworkPacket));
clientMap.erase(packet.clientInfo.index);
//delete players
erase_if(playerMap, [&](pair<int, Player> it) -> bool {
if (it.second.clientIndex == packet.clientInfo.index) {
NetworkPacket delPacket;
//data to delete one specific player
delPacket.meta.type = NetworkPacket::Type::PLAYER_DELETE;
delPacket.playerInfo.playerIndex = it.first;
//send to all
PumpPacket(delPacket);
return true;
}
return false;
});
cout << "disconnect, total: " << clientMap.size() << endl;
}
void ServerApplication::HandleSynchronize(NetworkPacket packet) {
//send all the server's data to this client
NetworkPacket newPacket;
//players
newPacket.meta.type = NetworkPacket::Type::PLAYER_UPDATE;
for (auto& it : playerMap) {
newPacket.playerInfo.playerIndex = it.first;
snprintf(newPacket.playerInfo.handle, PACKET_STRING_SIZE, "%s", it.second.handle.c_str());
snprintf(newPacket.playerInfo.avatar, PACKET_STRING_SIZE, "%s", it.second.avatar.c_str());
newPacket.playerInfo.position = it.second.position;
newPacket.playerInfo.motion = it.second.motion;
network.Send(&clientMap[packet.clientInfo.index].address, &newPacket, sizeof(NetworkPacket));
} }
} }
void ServerApplication::HandleShutdown(NetworkPacket packet) { void ServerApplication::HandleBroadcast(Packet& bcast) {
//end the server //respond to a broadcast request with the server's data
running = false; Packet p;
p.meta.type = Packet::Type::BROADCAST_RESPONSE;
//disconnect all clients snprintf(p.serverInfo.name, PACKET_STRING_SIZE, "%s", configUtil->CString("server.name"));
packet.meta.type = NetworkPacket::Type::DISCONNECT; //TODO version information
PumpPacket(packet); netUtil->Send(&bcast.meta.address, &p, sizeof(Packet));
cout << "shutting down" << endl;
} }
void ServerApplication::HandlePlayerNew(NetworkPacket packet) { void ServerApplication::HandleConnection(Packet& request) {
//create the new player object //create the entries
Player newPlayer; ClientEntry newClient = {
newPlayer.clientIndex = packet.playerInfo.clientIndex; uniqueIndex++,
newPlayer.handle = packet.playerInfo.handle; request.meta.address
newPlayer.avatar = packet.playerInfo.avatar; };
newPlayer.position = {0,0};
newPlayer.motion = {0,0};
//push this player //push this information
playerMap[playerCounter] = newPlayer; clients[newClient.index] = newClient;
//send the client their info //send the player their information
packet.playerInfo.playerIndex = playerCounter; Packet p;
packet.playerInfo.position = playerMap[playerCounter].position; p.meta.type = Packet::Type::JOIN_RESPONSE;
packet.playerInfo.motion = playerMap[playerCounter].motion; p.meta.clientIndex = newClient.index;
//actually send to everyone //TODO: resource list
PumpPacket(packet);
//finish this routine netUtil->Send(&newClient.address, &p, sizeof(Packet));
playerCounter++;
//debugging
cout << "New connection: index " << newClient.index << endl;
cout << "number of clients: " << clients.size() << endl;
} }
void ServerApplication::HandlePlayerDelete(NetworkPacket packet) { void ServerApplication::HandleDisconnection(Packet& disconnect) {
if (playerMap.find(packet.playerInfo.playerIndex) == playerMap.end()) { //disconnect a client (redundant message)
throw(std::runtime_error("Cannot delete a non-existant player")); netUtil->Send(&clients[disconnect.meta.clientIndex].address, &disconnect, sizeof(Packet));
clients.erase(disconnect.meta.clientIndex);
//TODO remove the player...
//remove if(...)
//remove the player from other clients
//debugging
cout << "Lost connection: index " << disconnect.meta.clientIndex << endl;
cout << "number of clients: " << clients.size() << endl;
}
void ServerApplication::AddPlayer(Packet& p) {
//add the player
PlayerEntry newPlayer = {
uniqueIndex++,
p.meta.clientIndex,
p.playerInfo.handle,
p.playerInfo.avatar,
p.playerInfo.position,
p.playerInfo.motion
};
players[newPlayer.index] = newPlayer;
//prep for relay
p.playerInfo.index = newPlayer.index;
//debugging
cout << "New player " << newPlayer.handle << " has joined the game" << endl;
cout << "Number of players: " << players.size() << endl;
}
void ServerApplication::RemovePlayer(Packet& p) {
if (players.find(p.playerInfo.index) == players.end()) {
throw(runtime_error("Player to delete not found"));
} }
//delete players players.erase(p.playerInfo.index);
erase_if(playerMap, [&](pair<int, Player> it) -> bool {
if (it.first == packet.playerInfo.playerIndex) {
NetworkPacket delPacket;
//data to delete one specific player
delPacket.meta.type = NetworkPacket::Type::PLAYER_DELETE;
delPacket.playerInfo.playerIndex = it.first;
//send to all
PumpPacket(delPacket);
return true;
}
return false;
});
} }
void ServerApplication::HandlePlayerUpdate(NetworkPacket packet) { void ServerApplication::UpdatePlayer(Packet& p) {
if (playerMap.find(packet.playerInfo.playerIndex) == playerMap.end()) { if (players.find(p.playerInfo.index) == players.end()) {
throw(std::runtime_error("Cannot update a non-existant player")); throw(runtime_error("Player to update not found"));
} }
players[p.playerInfo.index].position = p.playerInfo.position;
//server is the slave to the clients, but only for now players[p.playerInfo.index].motion = p.playerInfo.motion;
playerMap[packet.playerInfo.playerIndex].position = packet.playerInfo.position;
playerMap[packet.playerInfo.playerIndex].motion = packet.playerInfo.motion;
PumpPacket(packet);
} }
void ServerApplication::PumpPacket(NetworkPacket packet) {
//send this packet to all clients
for (auto& it : clientMap) {
network.Send(&it.second.address, &packet, sizeof(NetworkPacket));
}
}
+46 -40
View File
@@ -22,67 +22,73 @@
#ifndef SERVERAPPLICATION_HPP_ #ifndef SERVERAPPLICATION_HPP_
#define SERVERAPPLICATION_HPP_ #define SERVERAPPLICATION_HPP_
//networking #include "packet.hpp"
#include "network_packet.hpp" #include "singleton.hpp"
#include "network_queue.hpp"
#include "config_Utility.hpp"
#include "udp_network_utility.hpp" #include "udp_network_utility.hpp"
//APIs
#include "sqlite3/sqlite3.h"
#include "SDL/SDL.h"
//misc
#include "config_utility.hpp"
#include "vector2.hpp" #include "vector2.hpp"
#include "client.hpp" #include "SDL/SDL_thread.h"
#include "player.hpp"
//STL
#include <map> #include <map>
#include <string> #include <string>
#include <algorithm>
struct ClientEntry {
int index;
IPaddress address;
};
struct PlayerEntry {
int index;
int clientIndex;
std::string handle;
std::string avatar;
Vector2 position;
Vector2 motion;
};
//The main application class
class ServerApplication { class ServerApplication {
public: public:
//standard functions
ServerApplication(); ServerApplication();
~ServerApplication(); ~ServerApplication();
void Init();
void Init(int argc, char** argv); void Proc();
void Loop();
void Quit(); void Quit();
ServerApplication(ServerApplication const&) = delete;
ServerApplication(ServerApplication const&&) = delete;
private: private:
void HandlePacket(NetworkPacket); //game loop
void UpdateWorld(double delta);
//high cohesion utility functions //network loop
void HandleBroadcastRequest(NetworkPacket); int HandlePacket(Packet);
void HandleJoinRequest(NetworkPacket); void RelayPacket(Packet&);
void HandleDisconnect(NetworkPacket);
void HandleSynchronize(NetworkPacket);
void HandleShutdown(NetworkPacket);
void HandlePlayerNew(NetworkPacket);
void HandlePlayerDelete(NetworkPacket);
void HandlePlayerUpdate(NetworkPacket);
void PumpPacket(NetworkPacket); void SynchronizeEverything(Packet&);
//networking void HandleBroadcast(Packet&);
UDPNetworkUtility network; void HandleConnection(Packet&);
void HandleDisconnection(Packet&);
//database void AddPlayer(Packet&);
sqlite3* database = nullptr; void RemovePlayer(Packet&);
void UpdatePlayer(Packet&);
//misc //services
bool running = true; ConfigUtility* configUtil = Singleton<ConfigUtility>::Get();
ConfigUtility config; UDPNetworkUtility* netUtil = Singleton<UDPNetworkUtility>::Get();
//global lists //members
ClientMap clientMap; std::map<int, ClientEntry> clients;
PlayerMap playerMap; std::map<int, PlayerEntry> players;
int clientCounter = 0; bool running = false;
int playerCounter = 0;
int uniqueIndex = 0;
}; };
#endif #endif
+7
View File
@@ -0,0 +1,7 @@
#include <iostream>
using namespace std;
int main(int, char**) {
return 0;
}
+8 -13
View File
@@ -1,25 +1,23 @@
#config #config
INCLUDES+=. .. LOCALLIBS=../lib/libCommon.a
LIBS+= LIB=
INCLUDES=../common
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES)) CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
#source #source
CXXSRC=$(wildcard *.cpp) SRC=$(wildcard *.cpp)
CSRC=$(wildcard *.c)
#objects #objects
OBJDIR=obj OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o)) OBJ=$(addprefix $(OBJDIR)/,$(SRC:.cpp=.o))
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
#output #output
OUTDIR=../.. OUTDIR=../out
OUT=$(addprefix $(OUTDIR)/,libcommon.a) OUT=$(addprefix $(OUTDIR)/,test)
#targets #targets
all: $(OBJ) $(OUT) all: $(OBJ) $(OUT)
ar -crs $(OUT) $(OBJ) $(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIB)
$(OBJ): | $(OBJDIR) $(OBJ): | $(OBJDIR)
@@ -34,9 +32,6 @@ $(OUTDIR):
$(OBJDIR)/%.o: %.cpp $(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $< $(CXX) $(CXXFLAGS) -c -o $@ $<
$(OBJDIR)/%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean: clean:
$(RM) *.o *.a *.exe $(RM) *.o *.a *.exe