Compare commits
81 Commits
release-0.1
..
old
| Author | SHA1 | Date | |
|---|---|---|---|
| 65135b4b86 | |||
| 51a0974d25 | |||
| a23156c425 | |||
| c03743ed0c | |||
| ee3877b906 | |||
| c4bcced984 | |||
| 40a40b4e11 | |||
| 43dadcdbb8 | |||
| 28b491587c | |||
| 977c2b24fb | |||
| 99bbe4be3a | |||
| 4dc05f8daf | |||
| b7205c278a | |||
| 6bee9b021d | |||
| a49b0eb1fe | |||
| 2089105695 | |||
| f667f503e7 | |||
| 50bef9736c | |||
| 6d1ba24404 | |||
| ebd8c5e6fc | |||
| 42f9c5e1df | |||
| 3f2fcdf9e1 | |||
| 2235f307e7 | |||
| 23782ff4e3 | |||
| 2a46f82f84 | |||
| 6a32599a69 | |||
| 0ca84a8653 | |||
| 66b2d6566c | |||
| 56375d64b6 | |||
| 9608761cd5 | |||
| c1d03d1cef | |||
| 09c88c7232 | |||
| ddb93cfcf1 | |||
| 42787dcb69 | |||
| fcb17a8116 | |||
| 2dc21f64fd | |||
| f049c96df7 | |||
| d9ffa22b76 | |||
| 24654d9e17 | |||
| 7ad855348f | |||
| d833b76856 | |||
| 3232925ccd | |||
| e4ffba80aa | |||
| a4d184ca75 | |||
| 89179626be | |||
| fc381348a5 | |||
| 5e99192fbf | |||
| 33adb4b1a5 | |||
| 33474cc6c0 | |||
| e833129983 | |||
| fd65fec5f7 | |||
| 69f03cd250 | |||
| 27ed91688a | |||
| 68ec7323a3 | |||
| 7b11bf22cb | |||
| d83a536f35 | |||
| ea761fb5bb | |||
| 685ca94335 | |||
| 5b2fd80a61 | |||
| d1aac9ffd8 | |||
| 3d92fb77b3 | |||
| 009e7b845b | |||
| 752dcadfa1 | |||
| 9599d82db3 | |||
| 7fef2501a3 | |||
| 419c9d8765 | |||
| a0fa874a29 | |||
| 5110ebc1b2 | |||
| 843053d307 | |||
| 2148c1f13e | |||
| f3ec4d4d8e | |||
| cbd388f4ed | |||
| 37a9e4268b | |||
| dfe0b4985a | |||
| 7ca7f7f015 | |||
| c21a95f3e9 | |||
| 0a48131de4 | |||
| 78326a3bbd | |||
| 253e9ec8fc | |||
| a1b248d1d7 | |||
| 2757911399 |
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
#Editor generated files
|
#Editor generated files
|
||||||
*.sln
|
#*.sln
|
||||||
*.vcproj
|
#*.vcproj
|
||||||
*.suo
|
*.suo
|
||||||
*.ncb
|
*.ncb
|
||||||
*.user
|
*.user
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
#ifndef CHANNELS_HPP_
|
|
||||||
#define CHANNELS_HPP_
|
|
||||||
|
|
||||||
enum Channels {
|
|
||||||
SERVER = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -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"));
|
||||||
|
|||||||
@@ -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&);
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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));
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
@@ -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
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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 ℑ }
|
||||||
|
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;
|
||||||
};
|
};
|
||||||
@@ -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
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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;
|
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
@@ -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
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
@@ -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(®ionList.front());
|
|
||||||
}
|
|
||||||
return ®ionList.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(®ionList.front());
|
|
||||||
}
|
|
||||||
return ®ionList.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++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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 ®ionList; }
|
|
||||||
private:
|
|
||||||
std::list<Region> regionList;
|
|
||||||
int regionWidth = 0, regionHeight = 0;
|
|
||||||
|
|
||||||
regionCallback_t onNew = nullptr;
|
|
||||||
regionCallback_t onDelete = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -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
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
@@ -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 ℑ }
|
|
||||||
|
|
||||||
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
|
|
||||||
@@ -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"));
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
};
|
};
|
||||||
@@ -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
|
||||||
@@ -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 ℑ } //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
|
||||||
@@ -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) {
|
||||||
@@ -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
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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
@@ -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; }
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
@@ -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) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
@@ -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
@@ -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 |
@@ -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
@@ -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
@@ -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
@@ -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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int main(int, char**) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
|
||||||
Reference in New Issue
Block a user