Compare commits
81 Commits
release-0.2
..
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 |
@@ -1,6 +1,6 @@
|
|||||||
#Editor generated files
|
#Editor generated files
|
||||||
*.sln
|
#*.sln
|
||||||
*.vcproj
|
#*.vcproj
|
||||||
*.suo
|
*.suo
|
||||||
*.ncb
|
*.ncb
|
||||||
*.user
|
*.user
|
||||||
|
|||||||
@@ -1,26 +1,23 @@
|
|||||||
The most recent stable windows build can be found [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, exploration 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://github.com/Ratstail91/Tortuga/blob/docs/design%20doc.docx?raw=true)
|
* You can read more details on the Tortuga wiki [here](https://github.com/Ratstail91/Tortuga/wiki).
|
||||||
[Tortuga Technical Document](https://github.com/Ratstail91/Tortuga/blob/docs/technical%20doc.docx?raw=true)
|
|
||||||
|
|
||||||
## Copyright
|
## Copyright
|
||||||
|
|
||||||
The current version of Tortuga is released under the [zlib license](http://en.wikipedia.org/wiki/Zlib_License).
|
The current version of Tortuga is released under the [zlib license](http://en.wikipedia.org/wiki/Zlib_License).
|
||||||
|
|
||||||
Copyright (c) 2013, 2014 Kayne Ruse
|
Copyright (c) 2013 Kayne Ruse
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
@@ -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_FULLSCREEN : SDL_HWSURFACE|SDL_DOUBLEBUF);
|
|
||||||
|
|
||||||
//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, PACKET_BUFFER_SIZE);
|
|
||||||
|
//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;
|
||||||
|
|
||||||
std::chrono::duration<int, std::milli> delta(16);
|
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,13 +110,15 @@ 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) {
|
||||||
//call each user defined function
|
//call each user defined function
|
||||||
activeScene->RunFrame(double(delta.count()) / std::chrono::duration<int, std::milli>::period::den);
|
activeScene->RunFrame(double(delta.count()) / Clock::duration::period::den);
|
||||||
simTime += delta;
|
simTime += delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +130,14 @@ void ClientApplication::Proc() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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();
|
||||||
}
|
}
|
||||||
@@ -118,27 +148,29 @@ void ClientApplication::Quit() {
|
|||||||
|
|
||||||
void ClientApplication::LoadScene(SceneList sceneIndex) {
|
void ClientApplication::LoadScene(SceneList sceneIndex) {
|
||||||
UnloadScene();
|
UnloadScene();
|
||||||
|
|
||||||
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));
|
||||||
|
}
|
||||||
@@ -19,27 +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 LOBBYMENU_HPP_
|
#ifndef INWORLD_HPP_
|
||||||
#define LOBBYMENU_HPP_
|
#define INWORLD_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 "player_character.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 "serial.hpp"
|
#include "raster_font.hpp"
|
||||||
|
#include "frame_rate.hpp"
|
||||||
|
|
||||||
#include <vector>
|
#include <map>
|
||||||
|
|
||||||
class LobbyMenu : public BaseScene {
|
class InWorld : public BaseScene {
|
||||||
public:
|
public:
|
||||||
//Public access members
|
//Public access members
|
||||||
LobbyMenu(ConfigUtility* const, UDPNetworkUtility* const, int* const);
|
InWorld();
|
||||||
~LobbyMenu();
|
~InWorld();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//Frame loop
|
//Frame loop
|
||||||
@@ -49,38 +54,35 @@ protected:
|
|||||||
void Render(SDL_Surface* const);
|
void Render(SDL_Surface* const);
|
||||||
|
|
||||||
//Event handlers
|
//Event handlers
|
||||||
|
void QuitEvent();
|
||||||
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&);
|
void KeyUp(SDL_KeyboardEvent const&);
|
||||||
|
|
||||||
void HandlePacket(NetworkPacket);
|
//Utilities
|
||||||
|
int HandlePacket(Packet);
|
||||||
|
void Disconnect();
|
||||||
|
void ExitGame();
|
||||||
|
|
||||||
//global
|
void HandleDisconnection(Packet&);
|
||||||
ConfigUtility& config;
|
|
||||||
UDPNetworkUtility& network;
|
void AddPlayer(Packet&);
|
||||||
int& clientIndex;
|
void RemovePlayer(Packet&);
|
||||||
|
void UpdatePlayer(Packet&);
|
||||||
|
|
||||||
|
void SendState();
|
||||||
|
|
||||||
|
//services
|
||||||
|
ConfigUtility* configUtil = Singleton<ConfigUtility>::Get();
|
||||||
|
SurfaceManager* surfaceMgr = Singleton<SurfaceManager>::Get();
|
||||||
|
UDPNetworkUtility* netUtil = Singleton<UDPNetworkUtility>::Get();
|
||||||
|
InformationManager* infoMgr = Singleton<InformationManager>::Get();
|
||||||
|
|
||||||
//members
|
//members
|
||||||
Image image;
|
|
||||||
RasterFont font;
|
RasterFont font;
|
||||||
Button search;
|
std::map<int, PlayerCharacter> playerCharacters;
|
||||||
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;
|
|
||||||
ServerInformation* selection = nullptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -19,30 +19,22 @@
|
|||||||
* 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 UTILITY_HPP_
|
#ifndef INFORMATIONMANAGER_HPP_
|
||||||
#define UTILITY_HPP_
|
#define INFORMATIONMANAGER_HPP_
|
||||||
|
|
||||||
#include <string>
|
class InformationManager {
|
||||||
|
public:
|
||||||
|
int SetClientIndex(int i) { return clientIndex = i; }
|
||||||
|
int GetClientIndex() { return clientIndex; }
|
||||||
|
void ResetClientIndex() { clientIndex = -1; }
|
||||||
|
|
||||||
int snapToBase(int base, int x);
|
//one player at a time
|
||||||
std::string truncatePath(std::string pathname);
|
int SetPlayerIndex(int i) { return playerIndex = i; }
|
||||||
|
int GetPlayerIndex() { return playerIndex; }
|
||||||
//fixing known bugs in g++
|
void ResetPlayerIndex() { playerIndex = -1; }
|
||||||
std::string to_string_custom(int i);
|
private:
|
||||||
|
int clientIndex = -1;
|
||||||
int to_integer_custom(std::string);
|
int playerIndex = -1;
|
||||||
|
|
||||||
//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
|
#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,21 +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 OPTIONSMENU_HPP_
|
#ifndef LOBBY_HPP_
|
||||||
#define OPTIONSMENU_HPP_
|
#define LOBBY_HPP_
|
||||||
|
|
||||||
#include "base_scene.hpp"
|
#include "base_scene.hpp"
|
||||||
|
|
||||||
#include "config_utility.hpp"
|
#include "defines.hpp"
|
||||||
#include "image.hpp"
|
#include "singleton.hpp"
|
||||||
#include "raster_font.hpp"
|
|
||||||
#include "button.hpp"
|
|
||||||
|
|
||||||
class OptionsMenu : public BaseScene {
|
#include "packet.hpp"
|
||||||
|
#include "network_queue.hpp"
|
||||||
|
#include "information_manager.hpp"
|
||||||
|
|
||||||
|
#include "config_utility.hpp"
|
||||||
|
#include "surface_manager.hpp"
|
||||||
|
#include "udp_network_utility.hpp"
|
||||||
|
#include "button.hpp"
|
||||||
|
#include "raster_font.hpp"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
struct ServerEntry {
|
||||||
|
std::string name;
|
||||||
|
IPaddress address;
|
||||||
|
//TODO: player count
|
||||||
|
};
|
||||||
|
|
||||||
|
class Lobby : public BaseScene {
|
||||||
public:
|
public:
|
||||||
//Public access members
|
//Public access members
|
||||||
OptionsMenu(ConfigUtility* const);
|
Lobby();
|
||||||
~OptionsMenu();
|
~Lobby();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//Frame loop
|
//Frame loop
|
||||||
@@ -49,13 +66,28 @@ protected:
|
|||||||
void KeyDown(SDL_KeyboardEvent const&);
|
void KeyDown(SDL_KeyboardEvent const&);
|
||||||
void KeyUp(SDL_KeyboardEvent const&);
|
void KeyUp(SDL_KeyboardEvent const&);
|
||||||
|
|
||||||
//globals
|
//utilities
|
||||||
ConfigUtility& config;
|
int HandlePacket(Packet);
|
||||||
|
void BroadcastNetwork();
|
||||||
|
void PushServer(Packet&);
|
||||||
|
void ConnectToServer(ServerEntry*);
|
||||||
|
void BeginGame(Packet&);
|
||||||
|
|
||||||
|
//services
|
||||||
|
ConfigUtility* configUtil = Singleton<ConfigUtility>::Get();
|
||||||
|
SurfaceManager* surfaceMgr = Singleton<SurfaceManager>::Get();
|
||||||
|
UDPNetworkUtility* netUtil = Singleton<UDPNetworkUtility>::Get();
|
||||||
|
InformationManager* infoMgr = Singleton<InformationManager>::Get();
|
||||||
|
|
||||||
//members
|
//members
|
||||||
Image image;
|
Button refreshButton;
|
||||||
RasterFont font;
|
Button joinButton;
|
||||||
Button backButton;
|
Button backButton;
|
||||||
|
|
||||||
|
RasterFont font;
|
||||||
|
SDL_Rect listBox;
|
||||||
|
std::vector<ServerEntry> serverList;
|
||||||
|
ServerEntry* selectedServer = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -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;
|
||||||
@@ -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,73 +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 "testificate_scene.hpp"
|
#include "option_screen.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
using std::cout;
|
using namespace std;
|
||||||
using std::endl;
|
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//Public access members
|
//Public access members
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
TestificateScene::TestificateScene(ConfigUtility* const arg1):
|
OptionScreen::OptionScreen() {
|
||||||
config(*arg1)
|
#ifdef DEBUG
|
||||||
{
|
cout << "entering OptionScreen" << endl;
|
||||||
//
|
#endif
|
||||||
|
backButton.Setup(50, 50, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Back");
|
||||||
}
|
}
|
||||||
|
|
||||||
TestificateScene::~TestificateScene() {
|
OptionScreen::~OptionScreen() {
|
||||||
//
|
#ifdef DEBUG
|
||||||
|
cout << "leaving OptionScreen" << endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//Frame loop
|
//Frame loop
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
void TestificateScene::FrameStart() {
|
void OptionScreen::Render(SDL_Surface* const screen) {
|
||||||
//
|
backButton.DrawTo(screen);
|
||||||
}
|
|
||||||
|
|
||||||
void TestificateScene::Update(double delta) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestificateScene::FrameEnd() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestificateScene::Render(SDL_Surface* const screen) {
|
|
||||||
//
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//Event handlers
|
//Event handlers
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
void TestificateScene::MouseMotion(SDL_MouseMotionEvent const& motion) {
|
void OptionScreen::MouseMotion(SDL_MouseMotionEvent const& motion) {
|
||||||
//
|
backButton.MouseMotion(motion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OptionScreen::MouseButtonDown(SDL_MouseButtonEvent const& button) {
|
||||||
void TestificateScene::MouseButtonDown(SDL_MouseButtonEvent const& button) {
|
backButton.MouseButtonDown(button);
|
||||||
//
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestificateScene::MouseButtonUp(SDL_MouseButtonEvent const& button) {
|
void OptionScreen::MouseButtonUp(SDL_MouseButtonEvent const& button) {
|
||||||
//
|
if (backButton.MouseButtonUp(button) == Button::State::HOVER) {
|
||||||
}
|
SetNextScene(SceneList::MAINMENU);
|
||||||
|
|
||||||
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) {
|
void OptionScreen::KeyDown(SDL_KeyboardEvent const& key) {
|
||||||
//
|
switch(key.keysym.sym) {
|
||||||
|
case SDLK_ESCAPE:
|
||||||
|
SetNextScene(SceneList::MAINMENU);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -19,35 +19,33 @@
|
|||||||
* 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 TESTIFICATESCENE_HPP_
|
#ifndef OPTIONSCREEN_HPP_
|
||||||
#define TESTIFICATESCENE_HPP_
|
#define OPTIONSCREEN_HPP_
|
||||||
|
|
||||||
#include "base_scene.hpp"
|
#include "base_scene.hpp"
|
||||||
|
#include "singleton.hpp"
|
||||||
|
|
||||||
#include "config_utility.hpp"
|
#include "surface_manager.hpp"
|
||||||
|
#include "button.hpp"
|
||||||
|
|
||||||
class TestificateScene : public BaseScene {
|
class OptionScreen : public BaseScene {
|
||||||
public:
|
public:
|
||||||
//Public access members
|
/* Public access members */
|
||||||
TestificateScene(ConfigUtility* const);
|
OptionScreen();
|
||||||
~TestificateScene();
|
~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;
|
Button backButton;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -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, int camX, int camY) { sprite.DrawTo(dest, position.x - camX, position.y - camY); }
|
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,499 +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 <algorithm>
|
|
||||||
#include <cmath>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
//debugging
|
|
||||||
#include <iostream>
|
|
||||||
using std::cout;
|
|
||||||
using std::endl;
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Public access members
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
InWorld::InWorld(ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex):
|
|
||||||
config(*argConfig),
|
|
||||||
network(*argNetwork),
|
|
||||||
clientIndex(*argClientIndex)
|
|
||||||
{
|
|
||||||
//setup the utility objects
|
|
||||||
buttonImage.LoadSurface(config["dir.interface"] + "button_menu.bmp");
|
|
||||||
buttonImage.SetClipH(buttonImage.GetClipH()/3);
|
|
||||||
font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp");
|
|
||||||
|
|
||||||
//pass the utility objects
|
|
||||||
disconnectButton.SetImage(&buttonImage);
|
|
||||||
disconnectButton.SetFont(&font);
|
|
||||||
shutDownButton.SetImage(&buttonImage);
|
|
||||||
shutDownButton.SetFont(&font);
|
|
||||||
|
|
||||||
//set the button positions
|
|
||||||
disconnectButton.SetX(50);
|
|
||||||
disconnectButton.SetY(50 + buttonImage.GetClipH() * 0);
|
|
||||||
shutDownButton.SetX(50);
|
|
||||||
shutDownButton.SetY(50 + buttonImage.GetClipH() * 1);
|
|
||||||
|
|
||||||
//set the button texts
|
|
||||||
disconnectButton.SetText("Disconnect");
|
|
||||||
shutDownButton.SetText("Shut Down");
|
|
||||||
|
|
||||||
//load the tilesheet
|
|
||||||
tileSheet.Load(config["dir.tilesets"] + "terrain.bmp", 12, 15);
|
|
||||||
|
|
||||||
//setup the map object
|
|
||||||
mapPager.SetRegionWidth(REGION_WIDTH);
|
|
||||||
mapPager.SetRegionHeight(REGION_HEIGHT);
|
|
||||||
mapPager.SetRegionDepth(REGION_DEPTH);
|
|
||||||
|
|
||||||
//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
|
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
|
||||||
serialize(&packet, buffer);
|
|
||||||
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
|
|
||||||
|
|
||||||
//request a sync
|
|
||||||
packet.meta.type = NetworkPacket::Type::SYNCHRONIZE;
|
|
||||||
serialize(&packet, buffer);
|
|
||||||
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
|
|
||||||
|
|
||||||
//debug
|
|
||||||
// RequestRegion(0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
InWorld::~InWorld() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Frame loop
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void InWorld::FrameStart() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void InWorld::Update(double delta) {
|
|
||||||
NetworkPacket packet;
|
|
||||||
|
|
||||||
//suck in all waiting packets
|
|
||||||
while(network.Receive()) {
|
|
||||||
deserialize(&packet, network.GetInData());
|
|
||||||
packet.meta.srcAddress = network.GetInPacket()->address;
|
|
||||||
HandlePacket(packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
//update the characters
|
|
||||||
for (auto& it : playerCharacters) {
|
|
||||||
it.second.Update(delta);
|
|
||||||
}
|
|
||||||
//TODO: sort the players and entities by Y position
|
|
||||||
|
|
||||||
//update the camera
|
|
||||||
if(localCharacter) {
|
|
||||||
camera.x = localCharacter->GetPosition().x - camera.marginX;
|
|
||||||
camera.y = localCharacter->GetPosition().y - camera.marginY;
|
|
||||||
}
|
|
||||||
|
|
||||||
//check the map
|
|
||||||
UpdateMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
void InWorld::FrameEnd() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void InWorld::RenderFrame() {
|
|
||||||
// SDL_FillRect(GetScreen(), 0, 0);
|
|
||||||
Render(GetScreen());
|
|
||||||
SDL_Flip(GetScreen());
|
|
||||||
}
|
|
||||||
|
|
||||||
void InWorld::Render(SDL_Surface* const screen) {
|
|
||||||
//draw the map
|
|
||||||
for (auto it = mapPager.GetContainer()->begin(); it != mapPager.GetContainer()->end(); it++) {
|
|
||||||
tileSheet.DrawRegionTo(screen, *it, camera.x, camera.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
//draw characters
|
|
||||||
for (auto& it : playerCharacters) {
|
|
||||||
it.second.DrawTo(screen, camera.x, camera.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
//draw UI
|
|
||||||
disconnectButton.DrawTo(screen);
|
|
||||||
shutDownButton.DrawTo(screen);
|
|
||||||
|
|
||||||
font.DrawStringTo(to_string_custom(fps.GetFrameRate()), screen, 0, 0);
|
|
||||||
|
|
||||||
fps.Calculate();
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Network handlers
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
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;
|
|
||||||
case NetworkPacket::Type::REGION_CONTENT:
|
|
||||||
HandleRegionContent(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];
|
|
||||||
//setup the camera
|
|
||||||
camera.width = GetScreen()->w;
|
|
||||||
camera.height = GetScreen()->h;
|
|
||||||
//center on the player's character
|
|
||||||
camera.marginX = (GetScreen()->w / 2 - localCharacter->GetSprite()->GetImage()->GetClipW() / 2);
|
|
||||||
camera.marginY = (GetScreen()->h / 2 - localCharacter->GetSprite()->GetImage()->GetClipH() / 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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::HandleRegionContent(NetworkPacket packet) {
|
|
||||||
//replace existing regions
|
|
||||||
if (mapPager.FindRegion(packet.regionInfo.x, packet.regionInfo.y)) {
|
|
||||||
mapPager.UnloadRegion(packet.regionInfo.x, packet.regionInfo.y);
|
|
||||||
}
|
|
||||||
mapPager.PushRegion(packet.regionInfo.region);
|
|
||||||
packet.regionInfo.region = nullptr;
|
|
||||||
|
|
||||||
//debugging
|
|
||||||
cout << "Received region: " << packet.regionInfo.x << ", " << packet.regionInfo.y << endl;
|
|
||||||
if (mapPager.FindRegion(packet.regionInfo.x, packet.regionInfo.y)) {
|
|
||||||
cout << "Success" << endl;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cout << "Failure" << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Server control
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void InWorld::SendState() {
|
|
||||||
NetworkPacket packet;
|
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
|
||||||
|
|
||||||
//pack the packet
|
|
||||||
packet.meta.type = NetworkPacket::Type::PLAYER_UPDATE;
|
|
||||||
packet.playerInfo.clientIndex = clientIndex;
|
|
||||||
packet.playerInfo.playerIndex = playerIndex;
|
|
||||||
packet.playerInfo.position = localCharacter->GetPosition();
|
|
||||||
packet.playerInfo.motion = localCharacter->GetMotion();
|
|
||||||
|
|
||||||
serialize(&packet, buffer);
|
|
||||||
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InWorld::RequestDisconnect() {
|
|
||||||
NetworkPacket packet;
|
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
|
||||||
|
|
||||||
//send a disconnect request
|
|
||||||
packet.meta.type = NetworkPacket::Type::DISCONNECT;
|
|
||||||
packet.clientInfo.index = clientIndex;
|
|
||||||
serialize(&packet, buffer);
|
|
||||||
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InWorld::RequestShutDown() {
|
|
||||||
NetworkPacket packet;
|
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
|
||||||
|
|
||||||
//send a shutdown request
|
|
||||||
packet.meta.type = NetworkPacket::Type::SHUTDOWN;
|
|
||||||
packet.clientInfo.index = clientIndex;
|
|
||||||
serialize(&packet, buffer);
|
|
||||||
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InWorld::RequestRegion(int x, int y) {
|
|
||||||
NetworkPacket packet;
|
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
|
||||||
|
|
||||||
//pack the region's data
|
|
||||||
packet.meta.type = NetworkPacket::Type::REGION_REQUEST;
|
|
||||||
packet.regionInfo.x = x;
|
|
||||||
packet.regionInfo.y = y;
|
|
||||||
serialize(&packet, buffer);
|
|
||||||
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Utilities
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
int InWorld::CheckBufferDistance(Region* const region) {
|
|
||||||
/* DOCUMENTATION
|
|
||||||
* This algorithm is extremely complex and involed, but initial tests show
|
|
||||||
* that it gives the right answers. The purpose is to determine how far off screen
|
|
||||||
* a certain region is, so that it can be unloaded when necessary.
|
|
||||||
*
|
|
||||||
* If the region is actually onscreen, then there's no reason to run the rest, so
|
|
||||||
* the algorithm corrects for the camera's location, before checking the bounds of
|
|
||||||
* the screen.
|
|
||||||
*
|
|
||||||
* The next part is tricky. If X or Y is negative, then it is divided by the
|
|
||||||
* graphical size of the regions, resulting in a usable integer, representing how
|
|
||||||
* far from the screen it is in "region units". If, however, X or Y is larger than
|
|
||||||
* 0, than first, the size of the screen is subtracted from that variable, before
|
|
||||||
* it is then divided by the graphical size of a region. Finally, to compensate for
|
|
||||||
* the off by one error, 1 is added at the end.
|
|
||||||
*
|
|
||||||
* Since only the magnitude of the distance in either direction is needed, this
|
|
||||||
* method returns the largest absolute value of X or Y.
|
|
||||||
*
|
|
||||||
* The final result of this algorithm is an integer representing how far, rounded
|
|
||||||
* up, a certain region is from the screen's edges in any direction, measured in
|
|
||||||
* "region units". This algorithm may be flawed, in which case, I recommend simply
|
|
||||||
* replacing it with a boolean check, to see if the region's distance from the player
|
|
||||||
* is larger than a certain value. This algorithm lacks the advantages I initially
|
|
||||||
* expected, so that may be beneficial at some point.
|
|
||||||
*/
|
|
||||||
|
|
||||||
//locations relative to the camera
|
|
||||||
int x = region->GetX() - camera.x;
|
|
||||||
int y = region->GetY() - camera.y;
|
|
||||||
|
|
||||||
//if the region is visible, return -1
|
|
||||||
if (x >= -mapPager.GetRegionWidth() * tileSheet.GetTileW() && x < camera.width &&
|
|
||||||
y >= -mapPager.GetRegionHeight() * tileSheet.GetTileH() && y < camera.height) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//prune the screen's area from the algorithm; get the pseudo-indexes
|
|
||||||
if (x < 0) x /= (mapPager.GetRegionWidth() * tileSheet.GetTileW());
|
|
||||||
if (y < 0) y /= (mapPager.GetRegionHeight() * tileSheet.GetTileH());
|
|
||||||
if (x > 0) x = (x - camera.width) / (mapPager.GetRegionWidth() * tileSheet.GetTileW()) + 1;
|
|
||||||
if (y > 0) y = (y - camera.height) / (mapPager.GetRegionHeight() * tileSheet.GetTileH()) + 1;
|
|
||||||
|
|
||||||
//return the pseudo-index with the greatest magnitude
|
|
||||||
return std::max(abs(x), abs(y));
|
|
||||||
}
|
|
||||||
|
|
||||||
void InWorld::UpdateMap() {
|
|
||||||
//prune distant regions
|
|
||||||
for (auto it = mapPager.GetContainer()->begin(); it != mapPager.GetContainer()->end(); /* EMPTY */) {
|
|
||||||
if (CheckBufferDistance(*it) > 2) {
|
|
||||||
//debugging
|
|
||||||
cout << "unloading: " << (*it)->GetX() << ", " << (*it)->GetY() << endl;
|
|
||||||
|
|
||||||
mapPager.UnloadRegion((*it)->GetX(), (*it)->GetY());
|
|
||||||
|
|
||||||
//reset
|
|
||||||
it = mapPager.GetContainer()->begin();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: make the region units official
|
|
||||||
int regionUnitX = mapPager.GetRegionWidth() * tileSheet.GetTileW();
|
|
||||||
int regionUnitY = mapPager.GetRegionHeight() * tileSheet.GetTileH();
|
|
||||||
|
|
||||||
//request empty regions, including buffers (-1 & +1 region unit)
|
|
||||||
for (int i = snapToBase(regionUnitX, camera.x - regionUnitX); i <= snapToBase(regionUnitX, camera.x + camera.width + regionUnitX); i += regionUnitX) {
|
|
||||||
for (int j = snapToBase(regionUnitY, camera.y - regionUnitY); j <= snapToBase(regionUnitY, camera.y + camera.height + regionUnitY); j += regionUnitY) {
|
|
||||||
if (!mapPager.FindRegion(i, j)) {
|
|
||||||
RequestRegion(i, j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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.
|
|
||||||
*/
|
|
||||||
#ifndef INWORLD_HPP_
|
|
||||||
#define INWORLD_HPP_
|
|
||||||
|
|
||||||
//maps
|
|
||||||
#include "map_generator.hpp"
|
|
||||||
#include "map_file_format.hpp"
|
|
||||||
#include "region_pager.hpp"
|
|
||||||
|
|
||||||
//networking
|
|
||||||
#include "udp_network_utility.hpp"
|
|
||||||
#include "network_packet.hpp"
|
|
||||||
#include "serial.hpp"
|
|
||||||
|
|
||||||
//graphics
|
|
||||||
#include "image.hpp"
|
|
||||||
#include "raster_font.hpp"
|
|
||||||
#include "button.hpp"
|
|
||||||
#include "tile_sheet.hpp"
|
|
||||||
|
|
||||||
//common
|
|
||||||
#include "config_utility.hpp"
|
|
||||||
#include "frame_rate.hpp"
|
|
||||||
|
|
||||||
//client
|
|
||||||
#include "base_scene.hpp"
|
|
||||||
#include "player_character.hpp"
|
|
||||||
|
|
||||||
//STL
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
class InWorld : public BaseScene {
|
|
||||||
public:
|
|
||||||
//Public access members
|
|
||||||
InWorld(ConfigUtility* const, UDPNetworkUtility* const, int* const);
|
|
||||||
~InWorld();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
//Frame loop
|
|
||||||
void FrameStart();
|
|
||||||
void Update(double delta);
|
|
||||||
void FrameEnd();
|
|
||||||
void RenderFrame();
|
|
||||||
void Render(SDL_Surface* const);
|
|
||||||
|
|
||||||
//Event handlers
|
|
||||||
void QuitEvent();
|
|
||||||
void MouseMotion(SDL_MouseMotionEvent const&);
|
|
||||||
void MouseButtonDown(SDL_MouseButtonEvent const&);
|
|
||||||
void MouseButtonUp(SDL_MouseButtonEvent const&);
|
|
||||||
void KeyDown(SDL_KeyboardEvent const&);
|
|
||||||
void KeyUp(SDL_KeyboardEvent const&);
|
|
||||||
|
|
||||||
//Network handlers
|
|
||||||
void HandlePacket(NetworkPacket);
|
|
||||||
void HandleDisconnect(NetworkPacket);
|
|
||||||
void HandlePlayerNew(NetworkPacket);
|
|
||||||
void HandlePlayerDelete(NetworkPacket);
|
|
||||||
void HandlePlayerUpdate(NetworkPacket);
|
|
||||||
void HandleRegionContent(NetworkPacket);
|
|
||||||
|
|
||||||
//Server control
|
|
||||||
void SendState();
|
|
||||||
void RequestDisconnect();
|
|
||||||
void RequestShutDown();
|
|
||||||
void RequestRegion(int x, int y);
|
|
||||||
|
|
||||||
//utilities
|
|
||||||
int CheckBufferDistance(Region* const);
|
|
||||||
void UpdateMap();
|
|
||||||
|
|
||||||
//globals
|
|
||||||
ConfigUtility& config;
|
|
||||||
FrameRate fps;
|
|
||||||
UDPNetworkUtility& network;
|
|
||||||
int& clientIndex;
|
|
||||||
|
|
||||||
//graphics
|
|
||||||
Image buttonImage;
|
|
||||||
RasterFont font;
|
|
||||||
TileSheet tileSheet;
|
|
||||||
|
|
||||||
//map
|
|
||||||
RegionPager<BlankGenerator, DummyFormat> mapPager;
|
|
||||||
|
|
||||||
//UI
|
|
||||||
Button disconnectButton;
|
|
||||||
Button shutDownButton;
|
|
||||||
struct {
|
|
||||||
int x = 0, y = 0;
|
|
||||||
int width = 0, height = 0;
|
|
||||||
int marginX = 0, marginY = 0;
|
|
||||||
} camera;
|
|
||||||
|
|
||||||
//game
|
|
||||||
std::map<int, PlayerCharacter> playerCharacters;
|
|
||||||
PlayerCharacter* localCharacter = nullptr;
|
|
||||||
int playerIndex = -1;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,204 +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()) {
|
|
||||||
deserialize(&packet, network.GetInData());
|
|
||||||
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) {
|
|
||||||
//the vars
|
|
||||||
NetworkPacket packet;
|
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
|
||||||
|
|
||||||
//broadcast to the network, or a specific server
|
|
||||||
packet.meta.type = NetworkPacket::Type::BROADCAST_REQUEST;
|
|
||||||
serialize(&packet, buffer);
|
|
||||||
network.Send(config["server.host"].c_str(), config.Int("server.port"), buffer, PACKET_BUFFER_SIZE);
|
|
||||||
|
|
||||||
//reset the server list
|
|
||||||
serverInfo.clear();
|
|
||||||
selection = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (join.MouseButtonUp(button) == Button::State::HOVER && selection != nullptr) {
|
|
||||||
//the vars
|
|
||||||
NetworkPacket packet;
|
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
|
||||||
|
|
||||||
//join the selected server
|
|
||||||
packet.meta.type = NetworkPacket::Type::JOIN_REQUEST;
|
|
||||||
serialize(&packet, buffer);
|
|
||||||
network.Send(&selection->address, buffer, PACKET_BUFFER_SIZE);
|
|
||||||
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,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 "options_menu.hpp"
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Public access members
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
OptionsMenu::OptionsMenu(ConfigUtility* const argConfig):
|
|
||||||
config(*argConfig)
|
|
||||||
{
|
|
||||||
//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
|
|
||||||
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() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Frame loop
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void OptionsMenu::FrameStart() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void OptionsMenu::Update(double delta) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void OptionsMenu::FrameEnd() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void OptionsMenu::Render(SDL_Surface* const screen) {
|
|
||||||
backButton.DrawTo(screen);
|
|
||||||
|
|
||||||
font.DrawStringTo("Oh, were you looking for the options screen?", screen, 50, 30);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Event handlers
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void OptionsMenu::MouseMotion(SDL_MouseMotionEvent const& motion) {
|
|
||||||
backButton.MouseMotion(motion);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OptionsMenu::MouseButtonDown(SDL_MouseButtonEvent const& button) {
|
|
||||||
backButton.MouseButtonDown(button);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OptionsMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) {
|
|
||||||
if (backButton.MouseButtonUp(button) == Button::State::HOVER) {
|
|
||||||
SetNextScene(SceneList::MAINMENU);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OptionsMenu::KeyDown(SDL_KeyboardEvent const& key) {
|
|
||||||
switch(key.keysym.sym) {
|
|
||||||
case SDLK_ESCAPE:
|
|
||||||
SetNextScene(SceneList::MAINMENU);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OptionsMenu::KeyUp(SDL_KeyboardEvent const& key) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
@@ -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";
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/* 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 "frame_rate.hpp"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
typedef std::chrono::high_resolution_clock Clock;
|
||||||
|
|
||||||
|
static int frameCount = 0;
|
||||||
|
static int lastFrameRate = 0;
|
||||||
|
static Clock::time_point tick = Clock::now();
|
||||||
|
|
||||||
|
int clockFrameRate() {
|
||||||
|
frameCount++;
|
||||||
|
if (Clock::now() - tick >= std::chrono::duration<int>(1)) {
|
||||||
|
lastFrameRate = frameCount;
|
||||||
|
frameCount = 0;
|
||||||
|
tick = Clock::now();
|
||||||
|
}
|
||||||
|
return lastFrameRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getFrameRate() {
|
||||||
|
return lastFrameRate;
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2014
|
/* Copyright: (c) Kayne Ruse 2013
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
@@ -22,27 +22,7 @@
|
|||||||
#ifndef FRAMERATE_HPP_
|
#ifndef FRAMERATE_HPP_
|
||||||
#define FRAMERATE_HPP_
|
#define FRAMERATE_HPP_
|
||||||
|
|
||||||
#include <chrono>
|
int clockFrameRate();
|
||||||
|
int getFrameRate();
|
||||||
class FrameRate {
|
|
||||||
public:
|
|
||||||
typedef std::chrono::high_resolution_clock Clock;
|
|
||||||
|
|
||||||
FrameRate() = default;
|
|
||||||
int Calculate() {
|
|
||||||
frameCount++;
|
|
||||||
if (Clock::now() - tick >= std::chrono::duration<int>(1)) {
|
|
||||||
lastFrameRate = frameCount;
|
|
||||||
frameCount = 0;
|
|
||||||
tick = Clock::now();
|
|
||||||
}
|
|
||||||
return lastFrameRate;
|
|
||||||
}
|
|
||||||
int GetFrameRate() { return lastFrameRate; }
|
|
||||||
private:
|
|
||||||
int frameCount = 0;
|
|
||||||
int lastFrameRate = 0;
|
|
||||||
Clock::time_point tick = Clock::now();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
#config
|
|
||||||
INCLUDES+=. .. ../map
|
|
||||||
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,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;
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2014
|
|
||||||
*
|
|
||||||
* 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"
|
|
||||||
|
|
||||||
void TileSheet::Load(std::string fname, int xc, int yc) {
|
|
||||||
XCount = xc;
|
|
||||||
YCount = yc;
|
|
||||||
image.LoadSurface(fname);
|
|
||||||
image.SetClipW(image.GetClipW()/XCount);
|
|
||||||
image.SetClipH(image.GetClipH()/YCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TileSheet::Unload() {
|
|
||||||
image.FreeSurface();
|
|
||||||
XCount = YCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TileSheet::DrawTo(SDL_Surface* const dest, int x, int y, Region::type_t tile) {
|
|
||||||
//0 is invisible
|
|
||||||
if (tile == 0) return;
|
|
||||||
image.SetClipX((tile-1) % XCount * image.GetClipW());
|
|
||||||
image.SetClipY((tile-1) / XCount * image.GetClipH());
|
|
||||||
image.DrawTo(dest, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TileSheet::DrawRegionTo(SDL_Surface* const dest, Region* const region, int camX, int camY) {
|
|
||||||
Region::type_t tile = 0;
|
|
||||||
for (register int i = 0; i < region->GetWidth(); ++i) {
|
|
||||||
for (register int j = 0; j < region->GetHeight(); ++j) {
|
|
||||||
for (register int k = 0; k < region->GetDepth(); ++k) {
|
|
||||||
tile = region->GetTile(i, j, k);
|
|
||||||
//0 is invisible
|
|
||||||
if (tile == 0) continue;
|
|
||||||
image.SetClipX((tile-1) % XCount * image.GetClipW());
|
|
||||||
image.SetClipY((tile-1) / XCount * image.GetClipH());
|
|
||||||
image.DrawTo(dest,
|
|
||||||
region->GetX() + i * image.GetClipW() - camX,
|
|
||||||
region->GetY() + j * image.GetClipH() - camY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2014
|
|
||||||
*
|
|
||||||
* 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 "region.hpp"
|
|
||||||
|
|
||||||
#include "image.hpp"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
class TileSheet {
|
|
||||||
public:
|
|
||||||
TileSheet() = default;
|
|
||||||
TileSheet(std::string f, int x, int y) { Load(f, x, y); }
|
|
||||||
~TileSheet() = default;
|
|
||||||
|
|
||||||
void Load(std::string fname, int XCount, int YCount);
|
|
||||||
void Unload();
|
|
||||||
|
|
||||||
void DrawTo(SDL_Surface* const dest, int x, int y, Region::type_t tile);
|
|
||||||
void DrawRegionTo(SDL_Surface* const dest, Region* const region, int camX, int camY);
|
|
||||||
|
|
||||||
//accessors
|
|
||||||
Image* GetImage() { return ℑ }
|
|
||||||
int GetXCount() { return XCount; }
|
|
||||||
int GetYCount() { return YCount; }
|
|
||||||
int GetTileW() { return image.GetClipW(); }
|
|
||||||
int GetTileH() { return image.GetClipH(); }
|
|
||||||
private:
|
|
||||||
Image image;
|
|
||||||
int XCount = 0, YCount = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -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();
|
||||||
@@ -1,30 +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 script
|
|
||||||
$(MAKE) -C network
|
|
||||||
$(MAKE) -C ui
|
|
||||||
|
|
||||||
$(OBJ): | $(OBJDIR)
|
$(OBJ): | $(OBJDIR)
|
||||||
|
|
||||||
@@ -39,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,79 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2014
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
|
||||||
* arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any purpose,
|
|
||||||
* including commercial applications, and to alter it and redistribute it
|
|
||||||
* freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
* claim that you wrote the original software. If you use this software
|
|
||||||
* in a product, an acknowledgment in the product documentation would be
|
|
||||||
* appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
* misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
*/
|
|
||||||
#include "map_file_format.hpp"
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
void DummyFormat::Load(Region** const ptr, int width, int height, int depth, int x, int y) {
|
|
||||||
//EMPTY
|
|
||||||
}
|
|
||||||
|
|
||||||
void DummyFormat::Save(Region* const ptr) {
|
|
||||||
//EMPTY
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
void VerboseFormat::Load(Region** const ptr, int x, int y) {
|
|
||||||
//TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void VerboseFormat::Save(Region* const ptr) {
|
|
||||||
//TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void CompactFormat::Load(Region** const ptr, int x, int y) {
|
|
||||||
//TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void CompactFormat::Save(Region* const ptr) {
|
|
||||||
//TODO
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
void LuaFormat::Load(Region** const ptr, int width, int height, int depth, int x, int y) {
|
|
||||||
//something to load into
|
|
||||||
(*ptr) = new Region(width, height, depth, x, y);
|
|
||||||
|
|
||||||
//API hook
|
|
||||||
lua_getglobal(state, "Region");
|
|
||||||
lua_getfield(state, -1, "Load");
|
|
||||||
lua_pushlightuserdata(state, *ptr);
|
|
||||||
lua_pushstring(state, saveDir.c_str());
|
|
||||||
if (lua_pcall(state, 2, 1, 0) != LUA_OK) {
|
|
||||||
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(state, -1) ));
|
|
||||||
}
|
|
||||||
if (lua_toboolean(state, -1) == false) {
|
|
||||||
delete (*ptr);
|
|
||||||
(*ptr) = nullptr;
|
|
||||||
}
|
|
||||||
lua_pop(state, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LuaFormat::Save(Region* const ptr) {
|
|
||||||
//API hook
|
|
||||||
lua_getglobal(state, "Region");
|
|
||||||
lua_getfield(state, -1, "Save");
|
|
||||||
lua_pushlightuserdata(state, ptr);
|
|
||||||
lua_pushstring(state, saveDir.c_str());
|
|
||||||
if (lua_pcall(state, 2, 0, 0) != LUA_OK) {
|
|
||||||
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(state, -1) ));
|
|
||||||
}
|
|
||||||
lua_pop(state, 1);
|
|
||||||
}
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2014
|
|
||||||
*
|
|
||||||
* 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 MAPFILEFORMAT_HPP_
|
|
||||||
#define MAPFILEFORMAT_HPP_
|
|
||||||
|
|
||||||
#include "region.hpp"
|
|
||||||
|
|
||||||
#include "lua/lua.hpp"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
class DummyFormat {
|
|
||||||
public:
|
|
||||||
void Load(Region** const, int width, int height, int depth, int x, int y);
|
|
||||||
void Save(Region* const);
|
|
||||||
|
|
||||||
std::string SetSaveDir(std::string s) { return saveDir = s; }
|
|
||||||
std::string GetSaveDir() { return saveDir; }
|
|
||||||
private:
|
|
||||||
std::string saveDir;
|
|
||||||
};
|
|
||||||
/*
|
|
||||||
class VerboseFormat {
|
|
||||||
public:
|
|
||||||
void Load(Region** const, int width, int height, int depth, int x, int y);
|
|
||||||
void Save(Region* const);
|
|
||||||
|
|
||||||
std::string SetSaveDir(std::string s) { return saveDir = s; }
|
|
||||||
std::string GetSaveDir() { return saveDir; }
|
|
||||||
private:
|
|
||||||
std::string saveDir;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CompactFormat {
|
|
||||||
public:
|
|
||||||
void Load(Region** const, int width, int height, int depth, int x, int y);
|
|
||||||
void Save(Region* const);
|
|
||||||
|
|
||||||
std::string SetSaveDir(std::string s) { return saveDir = s; }
|
|
||||||
std::string GetSaveDir() { return saveDir; }
|
|
||||||
private:
|
|
||||||
std::string saveDir;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
class LuaFormat {
|
|
||||||
public:
|
|
||||||
void Load(Region** const, int width, int height, int depth, int x, int y);
|
|
||||||
void Save(Region* const);
|
|
||||||
|
|
||||||
std::string SetSaveDir(std::string s) { return saveDir = s; }
|
|
||||||
std::string GetSaveDir() { return saveDir; }
|
|
||||||
|
|
||||||
lua_State* SetLuaState(lua_State* L) { return state = L; }
|
|
||||||
lua_State* GetLuaState() { return state; }
|
|
||||||
private:
|
|
||||||
std::string saveDir;
|
|
||||||
lua_State* state = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2014
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
|
||||||
* arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any purpose,
|
|
||||||
* including commercial applications, and to alter it and redistribute it
|
|
||||||
* freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
* claim that you wrote the original software. If you use this software
|
|
||||||
* in a product, an acknowledgment in the product documentation would be
|
|
||||||
* appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
* misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
*/
|
|
||||||
#include "map_generator.hpp"
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
void BlankGenerator::Create(Region** const ptr, int width, int height, int depth, int x, int y) {
|
|
||||||
(*ptr) = new Region(width, height, depth, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BlankGenerator::Unload(Region* const ptr) {
|
|
||||||
delete ptr;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
void PerlinGenerator::Create(Region** const ptr, int width, int height, int depth, int x, int y) {
|
|
||||||
(*ptr) = new Region(width, height, depth, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PerlinGenerator::Unload(Region* const ptr) {
|
|
||||||
delete ptr;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
void LuaGenerator::Create(Region** const ptr, int width, int height, int depth, int x, int y) {
|
|
||||||
//something to work on
|
|
||||||
(*ptr) = new Region(width, height, depth, x, y);
|
|
||||||
|
|
||||||
//API hook
|
|
||||||
lua_getglobal(state, "Region");
|
|
||||||
lua_getfield(state, -1, "Create");
|
|
||||||
lua_pushlightuserdata(state, *ptr);
|
|
||||||
if (lua_pcall(state, 1, 0, 0) != LUA_OK) {
|
|
||||||
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(state, -1) ));
|
|
||||||
}
|
|
||||||
lua_pop(state, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LuaGenerator::Unload(Region* const ptr) {
|
|
||||||
//API hook
|
|
||||||
lua_getglobal(state, "Region");
|
|
||||||
lua_getfield(state, -1, "Unload");
|
|
||||||
lua_pushlightuserdata(state, ptr);
|
|
||||||
if (lua_pcall(state, 1, 0, 0) != LUA_OK) {
|
|
||||||
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(state, -1) ));
|
|
||||||
}
|
|
||||||
lua_pop(state, 1);
|
|
||||||
|
|
||||||
//clean up the memory
|
|
||||||
delete ptr;
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2014
|
|
||||||
*
|
|
||||||
* 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 MAPGENERATOR_HPP_
|
|
||||||
#define MAPGENERATOR_HPP_
|
|
||||||
|
|
||||||
#include "region.hpp"
|
|
||||||
|
|
||||||
#include "lua/lua.hpp"
|
|
||||||
|
|
||||||
class BlankGenerator {
|
|
||||||
public:
|
|
||||||
void Create(Region** const, int width, int height, int depth, int x, int y);
|
|
||||||
void Unload(Region* const);
|
|
||||||
private:
|
|
||||||
//
|
|
||||||
};
|
|
||||||
/*
|
|
||||||
class PerlinGenerator {
|
|
||||||
public:
|
|
||||||
void Create(Region** const, int width, int height, int depth, int x, int y);
|
|
||||||
void Unload(Region* const);
|
|
||||||
private:
|
|
||||||
//
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
class LuaGenerator {
|
|
||||||
public:
|
|
||||||
void Create(Region** const, int width, int height, int depth, int x, int y);
|
|
||||||
void Unload(Region* const);
|
|
||||||
|
|
||||||
lua_State* SetLuaState(lua_State* L) { return state = L; }
|
|
||||||
lua_State* GetLuaState() { return state; }
|
|
||||||
private:
|
|
||||||
lua_State* state = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2014
|
|
||||||
*
|
|
||||||
* 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"
|
|
||||||
|
|
||||||
Region::Region(int argWidth, int argHeight, int argDepth, int argX, int argY):
|
|
||||||
width(argWidth),
|
|
||||||
height(argHeight),
|
|
||||||
depth(argDepth),
|
|
||||||
x(argX),
|
|
||||||
y(argY)
|
|
||||||
{
|
|
||||||
tiles = new type_t**[width];
|
|
||||||
for (register int i = 0; i < width; ++i) {
|
|
||||||
tiles[i] = new type_t*[height];
|
|
||||||
for (register int j = 0; j < height; ++j) {
|
|
||||||
tiles[i][j] = new type_t[depth];
|
|
||||||
for (register int k = 0; k < depth; ++k) {
|
|
||||||
tiles[i][j][k] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Region::~Region() {
|
|
||||||
for (register int i = 0; i < width; ++i) {
|
|
||||||
for (register int j = 0; j < height; j++) {
|
|
||||||
delete tiles[i][j];
|
|
||||||
}
|
|
||||||
delete tiles[i];
|
|
||||||
}
|
|
||||||
delete tiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
Region::type_t Region::SetTile(int x, int y, int z, type_t v) {
|
|
||||||
return tiles[x][y][z] = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
Region::type_t Region::GetTile(int x, int y, int z) {
|
|
||||||
return tiles[x][y][z];
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2014
|
|
||||||
*
|
|
||||||
* 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_
|
|
||||||
|
|
||||||
//temporary?
|
|
||||||
#define REGION_WIDTH 20
|
|
||||||
#define REGION_HEIGHT 20
|
|
||||||
#define REGION_DEPTH 3
|
|
||||||
|
|
||||||
class Region {
|
|
||||||
public:
|
|
||||||
typedef unsigned short type_t;
|
|
||||||
|
|
||||||
Region() = delete;
|
|
||||||
Region(int width, int height, int depth, int x, int y);
|
|
||||||
~Region();
|
|
||||||
|
|
||||||
type_t SetTile(int x, int y, int z, type_t v);
|
|
||||||
type_t GetTile(int x, int y, int z);
|
|
||||||
|
|
||||||
//accessors
|
|
||||||
int GetWidth() const { return width; }
|
|
||||||
int GetHeight() const { return height; }
|
|
||||||
int GetDepth() const { return depth; }
|
|
||||||
int GetX() const { return x; }
|
|
||||||
int GetY() const { return y; }
|
|
||||||
private:
|
|
||||||
const int width;
|
|
||||||
const int height;
|
|
||||||
const int depth;
|
|
||||||
const int x;
|
|
||||||
const int y;
|
|
||||||
|
|
||||||
type_t*** tiles = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2014
|
|
||||||
*
|
|
||||||
* 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"
|
|
||||||
|
|
||||||
RegionPagerBase::RegionPagerBase(int argWidth, int argHeight, int argDepth):
|
|
||||||
regionWidth(argWidth),
|
|
||||||
regionHeight(argHeight),
|
|
||||||
regionDepth(argDepth)
|
|
||||||
{
|
|
||||||
//EMPTY
|
|
||||||
}
|
|
||||||
|
|
||||||
RegionPagerBase::~RegionPagerBase() {
|
|
||||||
//EMPTY
|
|
||||||
}
|
|
||||||
|
|
||||||
Region::type_t RegionPagerBase::SetTile(int x, int y, int z, Region::type_t v) {
|
|
||||||
Region* ptr = GetRegion(x, y);
|
|
||||||
return ptr->SetTile(x - ptr->GetX(), y - ptr->GetY(), z, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
Region::type_t RegionPagerBase::GetTile(int x, int y, int z) {
|
|
||||||
Region* ptr = GetRegion(x, y);
|
|
||||||
return ptr->GetTile(x - ptr->GetX(), y - ptr->GetY(), z);
|
|
||||||
}
|
|
||||||
|
|
||||||
Region* RegionPagerBase::GetRegion(int x, int y) {
|
|
||||||
//snap the coords
|
|
||||||
x = snapToBase(regionWidth, x);
|
|
||||||
y = snapToBase(regionHeight, y);
|
|
||||||
|
|
||||||
//get the region by various means
|
|
||||||
|
|
||||||
//TODO: revert this try/catch point
|
|
||||||
Region* ptr = nullptr;
|
|
||||||
ptr = FindRegion(x, y);
|
|
||||||
if (ptr) return ptr;
|
|
||||||
ptr = LoadRegion(x, y);
|
|
||||||
if (ptr) return ptr;
|
|
||||||
return CreateRegion(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
Region* RegionPagerBase::FindRegion(int x, int y) {
|
|
||||||
//find the region
|
|
||||||
for (std::list<Region*>::iterator it = regionList.begin(); it != regionList.end(); it++) {
|
|
||||||
if ((*it)->GetX() == x && (*it)->GetY() == y) {
|
|
||||||
return *it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Region* RegionPagerBase::PushRegion(Region* ptr) {
|
|
||||||
regionList.push_front(ptr);
|
|
||||||
return regionList.front();
|
|
||||||
}
|
|
||||||
@@ -1,157 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2014
|
|
||||||
*
|
|
||||||
* 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 "utility.hpp"
|
|
||||||
|
|
||||||
#include <list>
|
|
||||||
|
|
||||||
class RegionPagerBase {
|
|
||||||
public:
|
|
||||||
RegionPagerBase() = default;
|
|
||||||
RegionPagerBase(int regionWidth, int regionHeight, int regionDepth);
|
|
||||||
virtual ~RegionPagerBase();
|
|
||||||
|
|
||||||
//tile manipulation
|
|
||||||
Region::type_t SetTile(int x, int y, int z, Region::type_t v);
|
|
||||||
Region::type_t GetTile(int x, int y, int z);
|
|
||||||
|
|
||||||
//region manipulation
|
|
||||||
Region* GetRegion(int x, int y);
|
|
||||||
Region* FindRegion(int x, int y);
|
|
||||||
Region* PushRegion(Region*);
|
|
||||||
|
|
||||||
//interface
|
|
||||||
virtual Region* LoadRegion(int x, int y) = 0;
|
|
||||||
virtual Region* SaveRegion(int x, int y) = 0;
|
|
||||||
virtual Region* CreateRegion(int x, int y) = 0;
|
|
||||||
virtual void UnloadRegion(int x, int y) = 0;
|
|
||||||
//TODO: delete?
|
|
||||||
|
|
||||||
//accessors & mutators
|
|
||||||
//NOTE: don't change the sizes mid-program, it will cause issues
|
|
||||||
int SetRegionWidth(int i) { return regionWidth = i; }
|
|
||||||
int SetRegionHeight(int i) { return regionHeight = i; }
|
|
||||||
int SetRegionDepth(int i) { return regionDepth = i; }
|
|
||||||
|
|
||||||
int GetRegionWidth() const { return regionWidth; }
|
|
||||||
int GetRegionHeight() const { return regionHeight; }
|
|
||||||
int GetRegionDepth() const { return regionDepth; }
|
|
||||||
|
|
||||||
std::list<Region*>* GetContainer() { return ®ionList; }
|
|
||||||
protected:
|
|
||||||
int regionWidth;
|
|
||||||
int regionHeight;
|
|
||||||
int regionDepth;
|
|
||||||
std::list<Region*> regionList;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename MapGenerator, typename MapFileFormat>
|
|
||||||
class RegionPager : public RegionPagerBase {
|
|
||||||
public:
|
|
||||||
RegionPager() = default;
|
|
||||||
RegionPager(int w, int h, int d):
|
|
||||||
RegionPagerBase(w, h, d)
|
|
||||||
{
|
|
||||||
//EMPTY
|
|
||||||
}
|
|
||||||
~RegionPager() {
|
|
||||||
UnloadAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
Region* LoadRegion(int x, int y) {
|
|
||||||
//snap the coords
|
|
||||||
x = snapToBase(regionWidth, x);
|
|
||||||
y = snapToBase(regionHeight, y);
|
|
||||||
|
|
||||||
//load the region if possible
|
|
||||||
Region* ptr = nullptr;
|
|
||||||
format.Load(&ptr, regionWidth, regionHeight, regionDepth, x, y);
|
|
||||||
if (ptr) {
|
|
||||||
regionList.push_back(ptr);
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Region* SaveRegion(int x, int y) {
|
|
||||||
//snap the coords
|
|
||||||
x = snapToBase(regionWidth, x);
|
|
||||||
y = snapToBase(regionHeight, y);
|
|
||||||
|
|
||||||
//find & save the region
|
|
||||||
for (std::list<Region*>::iterator it = regionList.begin(); it != regionList.end(); it++) {
|
|
||||||
if ((*it)->GetX() == x && (*it)->GetY() == y) {
|
|
||||||
format.Save(*it);
|
|
||||||
return *it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Region* CreateRegion(int x, int y) {
|
|
||||||
//snap the coords
|
|
||||||
x = snapToBase(regionWidth, x);
|
|
||||||
y = snapToBase(regionHeight, y);
|
|
||||||
|
|
||||||
//create and push the object
|
|
||||||
Region* ptr = nullptr;
|
|
||||||
generator.Create(&ptr, regionWidth, regionHeight, regionDepth, x, y);
|
|
||||||
regionList.push_back(ptr);
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UnloadRegion(int x, int y) {
|
|
||||||
//snap the coords
|
|
||||||
x = snapToBase(regionWidth, x);
|
|
||||||
y = snapToBase(regionHeight, y);
|
|
||||||
|
|
||||||
for (std::list<Region*>::iterator it = regionList.begin(); it != regionList.end(); /* EMPTY */) {
|
|
||||||
if ((*it)->GetX() == x && (*it)->GetY() == y) {
|
|
||||||
generator.Unload(*it);
|
|
||||||
regionList.erase(it);
|
|
||||||
|
|
||||||
//reset the loop, because of reasons
|
|
||||||
it = regionList.begin();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void UnloadAll() {
|
|
||||||
for (auto& it : regionList) {
|
|
||||||
generator.Unload(it);
|
|
||||||
}
|
|
||||||
regionList.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
//accessors
|
|
||||||
MapGenerator* GetGenerator() { return &generator; }
|
|
||||||
MapFileFormat* GetFormat() { return &format; }
|
|
||||||
protected:
|
|
||||||
MapGenerator generator;
|
|
||||||
MapFileFormat format;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
#config
|
|
||||||
INCLUDES+=. .. ../map
|
|
||||||
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,299 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2014
|
|
||||||
*
|
|
||||||
* 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 "serial.hpp"
|
|
||||||
|
|
||||||
#include "map_generator.hpp"
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//internal serialization functions
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void serializeType(NetworkPacket* packet, char* buffer) {
|
|
||||||
memcpy(buffer, &packet->meta.type, sizeof(NetworkPacket::Type));
|
|
||||||
}
|
|
||||||
|
|
||||||
void serializeServer(NetworkPacket* packet, char* buffer) {
|
|
||||||
memcpy(buffer, &packet->meta.type, sizeof(NetworkPacket::Type));
|
|
||||||
buffer += sizeof(NetworkPacket::Type);
|
|
||||||
memcpy(buffer, packet->serverInfo.name, PACKET_STRING_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void serializeClient(NetworkPacket* packet, char* buffer) {
|
|
||||||
memcpy(buffer, &packet->meta.type, sizeof(NetworkPacket::Type));
|
|
||||||
buffer += sizeof(NetworkPacket::Type);
|
|
||||||
memcpy(buffer, &packet->clientInfo.index, sizeof(int));
|
|
||||||
}
|
|
||||||
|
|
||||||
void serializePlayer(NetworkPacket* packet, char* buffer) {
|
|
||||||
memcpy(buffer, &packet->meta.type, sizeof(NetworkPacket::Type));
|
|
||||||
buffer += sizeof(NetworkPacket::Type);
|
|
||||||
|
|
||||||
//indexes
|
|
||||||
memcpy(buffer, &packet->playerInfo.clientIndex, sizeof(int));
|
|
||||||
buffer += sizeof(int);
|
|
||||||
memcpy(buffer, &packet->playerInfo.playerIndex, sizeof(int));
|
|
||||||
buffer += sizeof(int);
|
|
||||||
|
|
||||||
//text
|
|
||||||
memcpy(buffer, packet->playerInfo.handle, PACKET_STRING_SIZE);
|
|
||||||
buffer += PACKET_STRING_SIZE;
|
|
||||||
memcpy(buffer, packet->playerInfo.avatar, PACKET_STRING_SIZE);
|
|
||||||
buffer += PACKET_STRING_SIZE;
|
|
||||||
|
|
||||||
//vectors
|
|
||||||
memcpy(buffer, &packet->playerInfo.position.x, sizeof(double));
|
|
||||||
buffer += sizeof(double);
|
|
||||||
memcpy(buffer, &packet->playerInfo.position.y, sizeof(double));
|
|
||||||
buffer += sizeof(double);
|
|
||||||
memcpy(buffer, &packet->playerInfo.motion.x, sizeof(double));
|
|
||||||
buffer += sizeof(double);
|
|
||||||
memcpy(buffer, &packet->playerInfo.motion.y, sizeof(double));
|
|
||||||
}
|
|
||||||
|
|
||||||
void serializeRegionFormat(NetworkPacket* packet, char* buffer) {
|
|
||||||
memcpy(buffer, &packet->meta.type, sizeof(NetworkPacket::Type));
|
|
||||||
buffer += sizeof(NetworkPacket::Type);
|
|
||||||
|
|
||||||
//size
|
|
||||||
memcpy(buffer, &packet->regionInfo.width, sizeof(int));
|
|
||||||
buffer += sizeof(int);
|
|
||||||
memcpy(buffer, &packet->regionInfo.height, sizeof(int));
|
|
||||||
buffer += sizeof(int);
|
|
||||||
memcpy(buffer, &packet->regionInfo.depth, sizeof(int));
|
|
||||||
buffer += sizeof(int);
|
|
||||||
|
|
||||||
//x & y
|
|
||||||
memcpy(buffer, &packet->regionInfo.x, sizeof(int));
|
|
||||||
buffer += sizeof(int);
|
|
||||||
memcpy(buffer, &packet->regionInfo.y, sizeof(int));
|
|
||||||
}
|
|
||||||
|
|
||||||
void serializeRegionContent(NetworkPacket* packet, char* buffer) {
|
|
||||||
//format
|
|
||||||
memcpy(buffer, &packet->meta.type, sizeof(NetworkPacket::Type));
|
|
||||||
buffer += sizeof(NetworkPacket::Type);
|
|
||||||
|
|
||||||
//size
|
|
||||||
*reinterpret_cast<int*>(buffer) = packet->regionInfo.region->GetWidth();
|
|
||||||
buffer += sizeof(int);
|
|
||||||
*reinterpret_cast<int*>(buffer) = packet->regionInfo.region->GetHeight();
|
|
||||||
buffer += sizeof(int);
|
|
||||||
*reinterpret_cast<int*>(buffer) = packet->regionInfo.region->GetDepth();
|
|
||||||
buffer += sizeof(int);
|
|
||||||
|
|
||||||
//x & y
|
|
||||||
*reinterpret_cast<int*>(buffer) = packet->regionInfo.region->GetX();
|
|
||||||
buffer += sizeof(int);
|
|
||||||
*reinterpret_cast<int*>(buffer) = packet->regionInfo.region->GetY();
|
|
||||||
buffer += sizeof(int);
|
|
||||||
|
|
||||||
//content
|
|
||||||
for (register int i = 0; i < packet->regionInfo.region->GetWidth(); i++) {
|
|
||||||
for (register int j = 0; j < packet->regionInfo.region->GetHeight(); j++) {
|
|
||||||
for (register int k = 0; k < packet->regionInfo.region->GetDepth(); k++) {
|
|
||||||
*reinterpret_cast<Region::type_t*>(buffer) = packet->regionInfo.region->GetTile(i, j, k);
|
|
||||||
buffer += sizeof(Region::type_t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//internal deserialization functions
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void deserializeType(NetworkPacket* packet, char* buffer) {
|
|
||||||
memcpy(&packet->meta.type, buffer, sizeof(NetworkPacket::Type));
|
|
||||||
}
|
|
||||||
|
|
||||||
void deserializeServer(NetworkPacket* packet, char* buffer) {
|
|
||||||
memcpy(&packet->meta.type, buffer, sizeof(NetworkPacket::Type));
|
|
||||||
buffer += sizeof(NetworkPacket::Type);
|
|
||||||
memcpy(packet->serverInfo.name, buffer, PACKET_STRING_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void deserializeClient(NetworkPacket* packet, char* buffer) {
|
|
||||||
memcpy(&packet->meta.type, buffer, sizeof(NetworkPacket::Type));
|
|
||||||
buffer += sizeof(NetworkPacket::Type);
|
|
||||||
memcpy(&packet->clientInfo.index, buffer, sizeof(int));
|
|
||||||
}
|
|
||||||
|
|
||||||
void deserializePlayer(NetworkPacket* packet, char* buffer) {
|
|
||||||
memcpy(&packet->meta.type, buffer, sizeof(NetworkPacket::Type));
|
|
||||||
buffer += sizeof(NetworkPacket::Type);
|
|
||||||
|
|
||||||
//indexes
|
|
||||||
memcpy(&packet->playerInfo.clientIndex, buffer, sizeof(int));
|
|
||||||
buffer += sizeof(int);
|
|
||||||
memcpy(&packet->playerInfo.playerIndex, buffer, sizeof(int));
|
|
||||||
buffer += sizeof(int);
|
|
||||||
|
|
||||||
//text
|
|
||||||
memcpy(packet->playerInfo.handle, buffer, PACKET_STRING_SIZE);
|
|
||||||
buffer += PACKET_STRING_SIZE;
|
|
||||||
memcpy(packet->playerInfo.avatar, buffer, PACKET_STRING_SIZE);
|
|
||||||
buffer += PACKET_STRING_SIZE;
|
|
||||||
|
|
||||||
//vectors
|
|
||||||
memcpy(&packet->playerInfo.position.x, buffer, sizeof(double));
|
|
||||||
buffer += sizeof(double);
|
|
||||||
memcpy(&packet->playerInfo.position.y, buffer, sizeof(double));
|
|
||||||
buffer += sizeof(double);
|
|
||||||
memcpy(&packet->playerInfo.motion.x, buffer, sizeof(double));
|
|
||||||
buffer += sizeof(double);
|
|
||||||
memcpy(&packet->playerInfo.motion.y, buffer, sizeof(double));
|
|
||||||
}
|
|
||||||
|
|
||||||
void deserializeRegionFormat(NetworkPacket* packet, char* buffer) {
|
|
||||||
memcpy(&packet->meta.type, buffer, sizeof(NetworkPacket::Type));
|
|
||||||
buffer += sizeof(NetworkPacket::Type);
|
|
||||||
|
|
||||||
//size
|
|
||||||
memcpy(&packet->regionInfo.width, buffer, sizeof(int));
|
|
||||||
buffer += sizeof(int);
|
|
||||||
memcpy(&packet->regionInfo.height, buffer, sizeof(int));
|
|
||||||
buffer += sizeof(int);
|
|
||||||
memcpy(&packet->regionInfo.depth, buffer, sizeof(int));
|
|
||||||
buffer += sizeof(int);
|
|
||||||
|
|
||||||
//x & y
|
|
||||||
memcpy(&packet->regionInfo.x, buffer, sizeof(int));
|
|
||||||
buffer += sizeof(int);
|
|
||||||
memcpy(&packet->regionInfo.y, buffer, sizeof(int));
|
|
||||||
}
|
|
||||||
|
|
||||||
void deserializeRegionContent(NetworkPacket* packet, char* buffer) {
|
|
||||||
//format
|
|
||||||
deserializeRegionFormat(packet, buffer);
|
|
||||||
buffer += sizeof(int) * 5 + sizeof(NetworkPacket::Type);
|
|
||||||
|
|
||||||
//content
|
|
||||||
BlankGenerator().Create(
|
|
||||||
&packet->regionInfo.region,
|
|
||||||
packet->regionInfo.width,
|
|
||||||
packet->regionInfo.height,
|
|
||||||
packet->regionInfo.depth,
|
|
||||||
packet->regionInfo.x,
|
|
||||||
packet->regionInfo.y
|
|
||||||
);
|
|
||||||
|
|
||||||
for (register int i = 0; i < packet->regionInfo.region->GetWidth(); i++) {
|
|
||||||
for (register int j = 0; j < packet->regionInfo.region->GetHeight(); j++) {
|
|
||||||
for (register int k = 0; k < packet->regionInfo.region->GetDepth(); k++) {
|
|
||||||
packet->regionInfo.region->SetTile(i, j, k, *reinterpret_cast<Region::type_t*>(buffer));
|
|
||||||
buffer += sizeof(Region::type_t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//the interface functions
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void serialize(NetworkPacket* packet, void* buffer) {
|
|
||||||
switch(packet->meta.type) {
|
|
||||||
//No extra data
|
|
||||||
case NetworkPacket::Type::NONE:
|
|
||||||
case NetworkPacket::Type::PING:
|
|
||||||
case NetworkPacket::Type::PONG:
|
|
||||||
case NetworkPacket::Type::BROADCAST_REQUEST:
|
|
||||||
case NetworkPacket::Type::JOIN_REQUEST:
|
|
||||||
case NetworkPacket::Type::SYNCHRONIZE:
|
|
||||||
serializeType(packet, reinterpret_cast<char*>(buffer));
|
|
||||||
break;
|
|
||||||
|
|
||||||
//Server info
|
|
||||||
case NetworkPacket::Type::BROADCAST_RESPONSE:
|
|
||||||
serializeServer(packet, reinterpret_cast<char*>(buffer));
|
|
||||||
break;
|
|
||||||
|
|
||||||
//Client info
|
|
||||||
case NetworkPacket::Type::JOIN_RESPONSE:
|
|
||||||
case NetworkPacket::Type::DISCONNECT:
|
|
||||||
case NetworkPacket::Type::SHUTDOWN:
|
|
||||||
serializeClient(packet, reinterpret_cast<char*>(buffer));
|
|
||||||
break;
|
|
||||||
|
|
||||||
//Player info
|
|
||||||
case NetworkPacket::Type::PLAYER_NEW:
|
|
||||||
case NetworkPacket::Type::PLAYER_DELETE:
|
|
||||||
case NetworkPacket::Type::PLAYER_UPDATE:
|
|
||||||
serializePlayer(packet, reinterpret_cast<char*>(buffer));
|
|
||||||
break;
|
|
||||||
|
|
||||||
//region info
|
|
||||||
case NetworkPacket::Type::REGION_REQUEST:
|
|
||||||
serializeRegionFormat(packet, reinterpret_cast<char*>(buffer));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NetworkPacket::Type::REGION_CONTENT:
|
|
||||||
serializeRegionContent(packet, reinterpret_cast<char*>(buffer));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void deserialize(NetworkPacket* packet, void* buffer) {
|
|
||||||
//find the type, so that you can actually deserialize the packet!
|
|
||||||
deserializeType(packet, reinterpret_cast<char*>(buffer));
|
|
||||||
switch(packet->meta.type) {
|
|
||||||
//No extra data
|
|
||||||
case NetworkPacket::Type::NONE:
|
|
||||||
case NetworkPacket::Type::PING:
|
|
||||||
case NetworkPacket::Type::PONG:
|
|
||||||
case NetworkPacket::Type::BROADCAST_REQUEST:
|
|
||||||
case NetworkPacket::Type::JOIN_REQUEST:
|
|
||||||
case NetworkPacket::Type::SYNCHRONIZE:
|
|
||||||
//NOTHING
|
|
||||||
break;
|
|
||||||
|
|
||||||
//Server info
|
|
||||||
case NetworkPacket::Type::BROADCAST_RESPONSE:
|
|
||||||
deserializeServer(packet, reinterpret_cast<char*>(buffer));
|
|
||||||
break;
|
|
||||||
|
|
||||||
//Client info
|
|
||||||
case NetworkPacket::Type::JOIN_RESPONSE:
|
|
||||||
case NetworkPacket::Type::DISCONNECT:
|
|
||||||
case NetworkPacket::Type::SHUTDOWN:
|
|
||||||
deserializeClient(packet, reinterpret_cast<char*>(buffer));
|
|
||||||
break;
|
|
||||||
|
|
||||||
//Player info
|
|
||||||
case NetworkPacket::Type::PLAYER_NEW:
|
|
||||||
case NetworkPacket::Type::PLAYER_DELETE:
|
|
||||||
case NetworkPacket::Type::PLAYER_UPDATE:
|
|
||||||
deserializePlayer(packet, reinterpret_cast<char*>(buffer));
|
|
||||||
break;
|
|
||||||
|
|
||||||
//region info
|
|
||||||
case NetworkPacket::Type::REGION_REQUEST:
|
|
||||||
deserializeRegionFormat(packet, reinterpret_cast<char*>(buffer));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NetworkPacket::Type::REGION_CONTENT:
|
|
||||||
deserializeRegionContent(packet, reinterpret_cast<char*>(buffer));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2014
|
|
||||||
*
|
|
||||||
* 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 SERIAL_HPP_
|
|
||||||
#define SERIAL_HPP_
|
|
||||||
|
|
||||||
#include "network_packet.hpp"
|
|
||||||
|
|
||||||
/* Sending regions are the largest type of packet
|
|
||||||
* content: width * height * depth * sizoeof(type)
|
|
||||||
* map format: sizeof(int) * 5
|
|
||||||
* metadata: sizeof(metadata)
|
|
||||||
*/
|
|
||||||
#define PACKET_BUFFER_SIZE REGION_WIDTH * REGION_HEIGHT * REGION_DEPTH * sizeof(Region::type_t) + sizeof(int) * 5 + sizeof(NetworkPacket::Metadata)
|
|
||||||
|
|
||||||
void serialize(NetworkPacket* const, void*);
|
|
||||||
void deserialize(NetworkPacket* const, void*);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -19,24 +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.
|
||||||
*/
|
*/
|
||||||
#include "editor_application.hpp"
|
#ifndef NETWORKQUEUE_HPP_
|
||||||
|
#define NETWORKQUEUE_HPP_
|
||||||
|
|
||||||
#include <stdexcept>
|
#include "packet.hpp"
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
using namespace std;
|
void beginQueueThread();
|
||||||
|
void endQueueThread();
|
||||||
|
void killQueueThread();
|
||||||
|
Packet peekNetworkPacket();
|
||||||
|
Packet popNetworkPacket();
|
||||||
|
void flushNetworkQueue();
|
||||||
|
|
||||||
int main(int, char**) {
|
#endif
|
||||||
cout << "Beginning editor" << endl;
|
|
||||||
try {
|
|
||||||
EditorApplication::GetInstance()->Init();
|
|
||||||
EditorApplication::GetInstance()->Proc();
|
|
||||||
EditorApplication::GetInstance()->Quit();
|
|
||||||
}
|
|
||||||
catch(exception& e) {
|
|
||||||
cerr << "Fatal exception thrown: " << e.what() << endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
cout << "Clean exit" << endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -19,11 +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 NETWORKPACKET_HPP_
|
#ifndef PACKETTYPE_HPP_
|
||||||
#define NETWORKPACKET_HPP_
|
#define PACKETTYPE_HPP_
|
||||||
|
|
||||||
#include "vector2.hpp"
|
#include "vector2.hpp"
|
||||||
#include "region.hpp"
|
|
||||||
|
|
||||||
#include "SDL/SDL_net.h"
|
#include "SDL/SDL_net.h"
|
||||||
|
|
||||||
@@ -31,47 +30,31 @@
|
|||||||
|
|
||||||
#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,
|
|
||||||
|
|
||||||
//map data
|
|
||||||
REGION_REQUEST = 13,
|
|
||||||
REGION_CONTENT = 14,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//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
|
||||||
@@ -80,38 +63,26 @@ union NetworkPacket {
|
|||||||
//TODO: version info
|
//TODO: version info
|
||||||
char name[PACKET_STRING_SIZE];
|
char name[PACKET_STRING_SIZE];
|
||||||
//TODO: player count
|
//TODO: player count
|
||||||
//TODO: map format
|
|
||||||
}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;
|
||||||
|
|
||||||
//map data
|
//zero the packet
|
||||||
struct RegionInformation {
|
Packet() {
|
||||||
Metadata meta;
|
|
||||||
int width, height, depth, x, y;
|
|
||||||
Region* region;
|
|
||||||
}regionInfo;
|
|
||||||
|
|
||||||
//defaults
|
|
||||||
NetworkPacket() {
|
|
||||||
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;
|
||||||
};
|
};
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
** $Id: linit.c,v 1.32 2011/04/08 19:17:36 roberto Exp $
|
|
||||||
** Initialization of libraries for lua.c and other clients
|
|
||||||
** See Copyright Notice in lua.h
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Modified for use in Tortuga, renamed to linit.cpp
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** If you embed Lua in your program and need to open the standard
|
|
||||||
** libraries, call luaL_openlibs in your program. If you need a
|
|
||||||
** different set of libraries, copy this file to your project and edit
|
|
||||||
** it to suit your needs.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#define linit_c
|
|
||||||
#define LUA_LIB
|
|
||||||
|
|
||||||
#include "lua/lua.hpp"
|
|
||||||
#include "region_api.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** these libs are loaded by lua.c and are readily available to any Lua
|
|
||||||
** program
|
|
||||||
*/
|
|
||||||
static const luaL_Reg loadedlibs[] = {
|
|
||||||
/* Standard libs */
|
|
||||||
{"_G", luaopen_base},
|
|
||||||
{LUA_LOADLIBNAME, luaopen_package},
|
|
||||||
{LUA_COLIBNAME, luaopen_coroutine},
|
|
||||||
{LUA_TABLIBNAME, luaopen_table},
|
|
||||||
{LUA_IOLIBNAME, luaopen_io},
|
|
||||||
{LUA_OSLIBNAME, luaopen_os},
|
|
||||||
{LUA_STRLIBNAME, luaopen_string},
|
|
||||||
{LUA_BITLIBNAME, luaopen_bit32},
|
|
||||||
{LUA_MATHLIBNAME, luaopen_math},
|
|
||||||
{LUA_DBLIBNAME, luaopen_debug},
|
|
||||||
|
|
||||||
/* custom libs */
|
|
||||||
{LUA_REGIONLIBNAME, luaopen_regionapi},
|
|
||||||
|
|
||||||
{NULL, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** these libs are preloaded and must be required before used
|
|
||||||
*/
|
|
||||||
static const luaL_Reg preloadedlibs[] = {
|
|
||||||
{NULL, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
LUALIB_API void luaL_openlibs (lua_State *L) {
|
|
||||||
const luaL_Reg *lib;
|
|
||||||
/* call open functions from 'loadedlibs' and set results to global table */
|
|
||||||
for (lib = loadedlibs; lib->func; lib++) {
|
|
||||||
luaL_requiref(L, lib->name, lib->func, 1);
|
|
||||||
lua_pop(L, 1); /* remove lib */
|
|
||||||
}
|
|
||||||
/* add open functions from 'preloadedlibs' into 'package.preload' table */
|
|
||||||
luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD");
|
|
||||||
for (lib = preloadedlibs; lib->func; lib++) {
|
|
||||||
lua_pushcfunction(L, lib->func);
|
|
||||||
lua_setfield(L, -2, lib->name);
|
|
||||||
}
|
|
||||||
lua_pop(L, 1); /* remove _PRELOAD table */
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2014
|
|
||||||
*
|
|
||||||
* 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_api.hpp"
|
|
||||||
|
|
||||||
#include "region.hpp"
|
|
||||||
|
|
||||||
static int setTile(lua_State* L) {
|
|
||||||
Region* ptr = (Region*)lua_touserdata(L, 1);
|
|
||||||
ptr->SetTile(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1, lua_tointeger(L, 4)-1, lua_tointeger(L, 5));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int getTile(lua_State* L) {
|
|
||||||
Region* ptr = (Region*)lua_touserdata(L, 1);
|
|
||||||
int ret = ptr->GetTile(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1, lua_tointeger(L, 4)-1);
|
|
||||||
lua_pushnumber(L, ret);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int getWidth(lua_State* L) {
|
|
||||||
Region* ptr = (Region*)lua_touserdata(L, 1);
|
|
||||||
lua_pushinteger(L, ptr->GetWidth());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int getHeight(lua_State* L) {
|
|
||||||
Region* ptr = (Region*)lua_touserdata(L, 1);
|
|
||||||
lua_pushinteger(L, ptr->GetHeight());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int getDepth(lua_State* L) {
|
|
||||||
Region* ptr = (Region*)lua_touserdata(L, 1);
|
|
||||||
lua_pushinteger(L, ptr->GetDepth());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int getX(lua_State* L) {
|
|
||||||
Region* ptr = (Region*)lua_touserdata(L, 1);
|
|
||||||
lua_pushinteger(L, ptr->GetX());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int getY(lua_State* L) {
|
|
||||||
Region* ptr = (Region*)lua_touserdata(L, 1);
|
|
||||||
lua_pushinteger(L, ptr->GetY());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dummy(lua_State* L) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const luaL_Reg regionlib[] = {
|
|
||||||
{"SetTile",setTile},
|
|
||||||
{"GetTile",getTile},
|
|
||||||
{"GetWidth",getWidth},
|
|
||||||
{"GetHeight",getHeight},
|
|
||||||
{"GetDepth",getDepth},
|
|
||||||
{"GetX",getX},
|
|
||||||
{"GetY",getY},
|
|
||||||
{"Create", dummy},
|
|
||||||
{"Unload", dummy},
|
|
||||||
{"Load", dummy},
|
|
||||||
{"Save", dummy},
|
|
||||||
{nullptr, nullptr}
|
|
||||||
};
|
|
||||||
|
|
||||||
LUAMOD_API int luaopen_regionapi(lua_State* L) {
|
|
||||||
luaL_newlib(L, regionlib);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2014
|
/* Copyright: (c) Kayne Ruse 2013
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
@@ -19,12 +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 REGIONAPI_HPP_
|
#ifndef SINGLETON_HPP_
|
||||||
#define REGIONAPI_HPP_
|
#define SINGLETON_HPP_
|
||||||
|
|
||||||
#include "lua/lua.hpp"
|
template<typename T>
|
||||||
|
class Singleton {
|
||||||
|
public:
|
||||||
|
static T* Get() {
|
||||||
|
return &instance;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
static T instance;
|
||||||
|
};
|
||||||
|
|
||||||
#define LUA_REGIONLIBNAME "Region"
|
template<typename T>
|
||||||
LUAMOD_API int luaopen_regionapi(lua_State* L);
|
T Singleton<T>::instance;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -19,35 +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.
|
||||||
*/
|
*/
|
||||||
#ifndef EDITORAPPLICATION_HPP_
|
#include "sprite_sheet.hpp"
|
||||||
#define EDITORAPPLICATION_HPP_
|
|
||||||
|
|
||||||
#include "scene_list.hpp"
|
void SpriteSheet::Update(double delta) {
|
||||||
#include "base_scene.hpp"
|
if (delay && (ticks += delta) >= delay) {
|
||||||
#include "config_utility.hpp"
|
if (++currentFrame >= maxFrames) {
|
||||||
|
currentFrame = 0;
|
||||||
|
}
|
||||||
|
ticks = 0;
|
||||||
|
}
|
||||||
|
image.SetClipX(currentFrame * image.GetClipW());
|
||||||
|
image.SetClipY(currentStrip * image.GetClipH());
|
||||||
|
}
|
||||||
|
|
||||||
class EditorApplication {
|
SDL_Surface* SpriteSheet::SetSurface(SDL_Surface* const s, Uint16 w, Uint16 h) {
|
||||||
private:
|
image.SetSurface(s);
|
||||||
EditorApplication();
|
image.SetClip({0, 0, w, h});
|
||||||
~EditorApplication();
|
currentFrame = 0; maxFrames = image.GetSurface()->w / image.GetClipW();
|
||||||
static EditorApplication instance;
|
currentStrip = 0; maxStrips = image.GetSurface()->h / image.GetClipH();
|
||||||
|
delay = ticks = 0;
|
||||||
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
|
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/* 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 SURFACEMANAGER_HPP_
|
||||||
|
#define SURFACEMANAGER_HPP_
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class SurfaceManager {
|
||||||
|
public:
|
||||||
|
SurfaceManager() = default;
|
||||||
|
~SurfaceManager() noexcept { FreeAll(); }
|
||||||
|
|
||||||
|
SDL_Surface* Load(std::string key, std::string fname);
|
||||||
|
SDL_Surface* Reload(std::string key, std::string fname);
|
||||||
|
SDL_Surface* Get(std::string key);
|
||||||
|
SDL_Surface* Set(std::string key, SDL_Surface* ptr);
|
||||||
|
void Free(std::string key);
|
||||||
|
void FreeAll();
|
||||||
|
|
||||||
|
SDL_Surface* operator[](std::string key) { return Get(key); };
|
||||||
|
private:
|
||||||
|
SDL_Surface* LoadSurface(std::string key, std::string fname);
|
||||||
|
typedef std::map<std::string, SDL_Surface*> MapType;
|
||||||
|
MapType surfaceMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
#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 / base * base - base;
|
|
||||||
}
|
|
||||||
return x / base * 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;
|
|
||||||
}
|
|
||||||
@@ -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,235 +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", "Close"},
|
|
||||||
{"Edit", "Set Tile", "Set Brush", "Script"},
|
|
||||||
{"Debug", "Debug On", "Debug Off", "Toggle", "Testificate"}
|
|
||||||
});
|
|
||||||
|
|
||||||
//setup the map
|
|
||||||
pager.SetRegionWidth(REGION_WIDTH);
|
|
||||||
pager.SetRegionHeight(REGION_HEIGHT);
|
|
||||||
pager.SetRegionDepth(REGION_DEPTH);
|
|
||||||
|
|
||||||
//debug
|
|
||||||
tsheet.Load(config["dir.tilesets"] + "terrain.bmp", 12, 15);
|
|
||||||
for (int i = 0; i < REGION_WIDTH; i++) {
|
|
||||||
for (int j = 0; j < REGION_HEIGHT; j++) {
|
|
||||||
pager.SetTile(i, j, 0, 14);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pager.SetTile(5, 10, 1, 48);
|
|
||||||
}
|
|
||||||
|
|
||||||
EditorScene::~EditorScene() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Frame loop
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void EditorScene::FrameStart() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorScene::Update(double delta) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorScene::FrameEnd() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorScene::Render(SDL_Surface* const screen) {
|
|
||||||
tsheet.DrawRegionTo(screen, pager.GetRegion(0, 0), camera.x, camera.y);
|
|
||||||
/* //debug
|
|
||||||
for (int i = 0; i < pager.GetRegionWidth()*2; i++) {
|
|
||||||
for (int j = 0; j < pager.GetRegionHeight()*2; j++) {
|
|
||||||
for (int k = 0; k < pager.GetRegionDepth(); k++) {
|
|
||||||
//TODO: skip the out-of-bounds regions
|
|
||||||
tsheet.DrawTo(
|
|
||||||
screen,
|
|
||||||
i*tsheet.GetTileW()-camera.x,
|
|
||||||
j*tsheet.GetTileH()-camera.y,
|
|
||||||
pager.GetTile(i,j,k)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
//draw a big bar across the top (hackish)
|
|
||||||
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, with a grey background
|
|
||||||
SDL_Rect clip = {
|
|
||||||
Sint16(debugInfo.GetClipW() - str.size() * font.GetCharW()),
|
|
||||||
Sint16(font.GetCharH() * line),
|
|
||||||
Uint16(str.size() * font.GetCharW()),
|
|
||||||
Uint16(font.GetCharH())
|
|
||||||
};
|
|
||||||
SDL_FillRect(debugInfo.GetSurface(), &clip, SDL_MapRGB(debugInfo.GetSurface()->format, 64, 64, 64));
|
|
||||||
font.DrawStringTo(str, debugInfo.GetSurface(), clip.x, clip.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Event handlers
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void EditorScene::MouseMotion(SDL_MouseMotionEvent const& motion) {
|
|
||||||
menuBar.MouseMotion(motion);
|
|
||||||
|
|
||||||
if (motion.state & SDL_BUTTON_RMASK) {
|
|
||||||
camera.x -= motion.xrel;
|
|
||||||
camera.y -= motion.yrel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorScene::MouseButtonDown(SDL_MouseButtonEvent const& button) {
|
|
||||||
menuBar.MouseButtonDown(button);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorScene::MouseButtonUp(SDL_MouseButtonEvent const& button) {
|
|
||||||
int entry, drop;
|
|
||||||
menuBar.MouseButtonUp(button, &entry, &drop);
|
|
||||||
HandleMenuOption(entry, drop);
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Members
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void EditorScene::HandleMenuOption(int entry, int 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: CLOSE
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1: //Edit
|
|
||||||
switch(drop) {
|
|
||||||
case 0:
|
|
||||||
//TODO: SET TILE
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
//TODO: SET BRUSH
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
//TODO: 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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 "config_utility.hpp"
|
|
||||||
#include "image.hpp"
|
|
||||||
#include "raster_font.hpp"
|
|
||||||
#include "menu_bar.hpp"
|
|
||||||
|
|
||||||
#include "region_pager.hpp"
|
|
||||||
#include "map_generator.hpp"
|
|
||||||
#include "map_file_format.hpp"
|
|
||||||
#include "tile_sheet.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&);
|
|
||||||
|
|
||||||
//members
|
|
||||||
void HandleMenuOption(int entry, int drop);
|
|
||||||
|
|
||||||
//globals
|
|
||||||
ConfigUtility& config;
|
|
||||||
|
|
||||||
//debugging tools
|
|
||||||
void DrawToDebugInfo(std::string, int line);
|
|
||||||
Image debugInfo;
|
|
||||||
bool debugOpen = true;
|
|
||||||
|
|
||||||
RasterFont font;
|
|
||||||
Image buttonImage;
|
|
||||||
MenuBar menuBar;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
int x = 0, y = 0;
|
|
||||||
} camera;
|
|
||||||
|
|
||||||
RegionPager<BlankGenerator, DummyFormat> pager;
|
|
||||||
TileSheet tsheet;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
#config
|
|
||||||
INCLUDES+=../common ../common/graphics ../common/map ../common/ui
|
|
||||||
LIBS+=../libcommon.a -lmingw32 -lSDLmain -lSDL -llua
|
|
||||||
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,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)
|
||||||
|
|||||||
@@ -1,29 +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/
|
|
||||||
|
|
||||||
#map system
|
|
||||||
map.pager.width = 20
|
|
||||||
map.pager.height = 20
|
|
||||||
map.pager.depth = 3
|
|
||||||
|
|
||||||
#player options
|
|
||||||
player.handle = username
|
|
||||||
player.avatar = elliot2.bmp
|
|
||||||
|
|
||||||
#debugging
|
#debugging
|
||||||
|
debug = true
|
||||||
|
avatar = elliot
|
||||||
|
handle = UserName
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 108 KiB |
|
Before Width: | Height: | Size: 108 KiB |
|
Before Width: | Height: | Size: 108 KiB |
|
Before Width: | Height: | Size: 108 KiB |
|
Before Width: | Height: | Size: 108 KiB |
@@ -1,29 +0,0 @@
|
|||||||
print("Lua script check OK (./rsc)")
|
|
||||||
|
|
||||||
function Region.Create(r)
|
|
||||||
print("Region:Create(r", Region.GetX(r), Region.GetY(r), ")")
|
|
||||||
for i = 1, Region.GetWidth(r) do
|
|
||||||
for j = 1, Region.GetHeight(r) do
|
|
||||||
if math.abs(i) == math.abs(j) then
|
|
||||||
Region.SetTile(r, i, j, 1, 50)
|
|
||||||
else
|
|
||||||
Region.SetTile(r, i, j, 1, 14)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
print("done")
|
|
||||||
end
|
|
||||||
|
|
||||||
function Region.Unload(r)
|
|
||||||
print("Region:Unload(r", Region.GetX(r), Region.GetY(r), ")")
|
|
||||||
end
|
|
||||||
|
|
||||||
--return true if file loaded, otherwise return false
|
|
||||||
function Region.Load(r, saveDir)
|
|
||||||
print("Region:Load(r,", saveDir, Region.GetX(r), Region.GetY(r), ")")
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
function Region.Save(r, saveDir)
|
|
||||||
print("Region:Save(r,", saveDir, Region.GetX(r), Region.GetY(r), ")")
|
|
||||||
end
|
|
||||||
@@ -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)
|
|
||||||
);
|
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,15 @@
|
|||||||
#config
|
#config
|
||||||
INCLUDES+=. ../common ../common/map ../common/script ../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
|
||||||
|
|
||||||
|
|||||||
@@ -21,341 +21,298 @@
|
|||||||
*/
|
*/
|
||||||
#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;
|
||||||
|
|
||||||
int runSQLScript(sqlite3* db, std::string fname) {
|
//-------------------------
|
||||||
ifstream is(fname);
|
//Quick and dirty
|
||||||
if (!is.is_open()) {
|
//-------------------------
|
||||||
return -1;
|
|
||||||
}
|
static std::string itos(int i) {
|
||||||
string script;
|
char buffer[20];
|
||||||
getline(is, script, '\0');
|
snprintf(buffer, 20, "%d", i);
|
||||||
is.close();
|
return std::string(buffer);
|
||||||
//TODO: flesh out this error if needed
|
|
||||||
if (sqlite3_exec(db, script.c_str(), nullptr, nullptr, nullptr) != SQLITE_OK) {
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//Define the public members
|
//Public access members
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
void ServerApplication::Init(int argc, char** argv) {
|
ServerApplication::ServerApplication() {
|
||||||
cout << "Beginning startup" << endl;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
//load config
|
|
||||||
config.Load("rsc\\config.cfg");
|
|
||||||
|
|
||||||
//Init SDL
|
|
||||||
if (SDL_Init(0)) {
|
|
||||||
throw(runtime_error("Failed to initialize SDL"));
|
|
||||||
}
|
|
||||||
cout << "Initialized SDL" << endl;
|
|
||||||
|
|
||||||
//Init SDL_net
|
|
||||||
if (SDLNet_Init()) {
|
|
||||||
throw(runtime_error("Failed to initialize SDL_net"));
|
|
||||||
}
|
|
||||||
network.Open(config.Int("server.port"), PACKET_BUFFER_SIZE);
|
|
||||||
cout << "Initialized SDL_net" << endl;
|
|
||||||
|
|
||||||
//Init SQL
|
|
||||||
ret = sqlite3_open_v2(config["server.dbname"].c_str(), &database, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, nullptr);
|
|
||||||
if (ret != SQLITE_OK || !database) {
|
|
||||||
throw(runtime_error(string() + "Failed to initialize SQL: " + sqlite3_errmsg(database) ));
|
|
||||||
}
|
|
||||||
cout << "Initialized SQL" << endl;
|
|
||||||
|
|
||||||
//setup the database
|
|
||||||
if (runSQLScript(database, config["dir.scripts"] + "setup_server.sql")) {
|
|
||||||
throw(runtime_error("Failed to initialize SQL's setup script"));
|
|
||||||
}
|
|
||||||
cout << "Initialized SQL's setup script" << endl;
|
|
||||||
|
|
||||||
//lua
|
|
||||||
luaState = luaL_newstate();
|
|
||||||
if (!luaState) {
|
|
||||||
throw(runtime_error("Failed to initialize lua"));
|
|
||||||
}
|
|
||||||
luaL_openlibs(luaState);
|
|
||||||
cout << "Initialized lua" << endl;
|
|
||||||
|
|
||||||
//run the startup script
|
|
||||||
if (luaL_dofile(luaState, (config["dir.scripts"] + "setup_server.lua").c_str())) {
|
|
||||||
throw(runtime_error(string() + "Failed to initialize lua's setup script: " + lua_tostring(luaState, -1) ));
|
|
||||||
}
|
|
||||||
cout << "Initialized lua's setup script" << endl;
|
|
||||||
|
|
||||||
//setup the map object
|
|
||||||
mapPager.SetRegionWidth(REGION_WIDTH);
|
|
||||||
mapPager.SetRegionHeight(REGION_HEIGHT);
|
|
||||||
mapPager.SetRegionDepth(REGION_DEPTH);
|
|
||||||
mapPager.GetGenerator()->SetLuaState(luaState);
|
|
||||||
mapPager.GetFormat()->SetLuaState(luaState);
|
|
||||||
mapPager.GetFormat()->SetSaveDir("save/mapname/");
|
|
||||||
//TODO: pass args to the generator & format as needed
|
|
||||||
//NOTE: I might need to rearrange the init process so that lua & SQL can interact
|
|
||||||
// with the map system as needed.
|
|
||||||
cout << "Initialized the map system" << endl;
|
|
||||||
cout << "\tsizeof(NetworkPacket): " << sizeof(NetworkPacket) << endl;
|
|
||||||
cout << "\tPACKET_BUFFER_SIZE: " << PACKET_BUFFER_SIZE << endl;
|
|
||||||
|
|
||||||
//finalize the startup
|
|
||||||
cout << "Startup completed successfully" << endl;
|
|
||||||
|
|
||||||
//debugging
|
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerApplication::Loop() {
|
ServerApplication::~ServerApplication() {
|
||||||
NetworkPacket packet;
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ServerApplication::Init()
|
||||||
|
* This function initializes the entire program. There are a number of things
|
||||||
|
* that could go wrong here, which is why there is such an unusual order of
|
||||||
|
* operations.
|
||||||
|
* Important things to note:
|
||||||
|
* The APIs are initiated here.
|
||||||
|
* The global objects are initialized here.
|
||||||
|
* The ConfigUtility's call to Load() also ensures that the "rsc\" folder is in the directory. It's easy to forget it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void ServerApplication::Init() {
|
||||||
|
//load the config file
|
||||||
|
try {
|
||||||
|
configUtil->Load("rsc/config.cfg");
|
||||||
|
}
|
||||||
|
catch(std::runtime_error& e) {
|
||||||
|
std::string s = e.what();
|
||||||
|
s += "; Ensure that the \"rsc\" directory is present";
|
||||||
|
throw(std::runtime_error(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
//check the port is valid
|
||||||
|
if (configUtil->Int("server.port") <= 0) {
|
||||||
|
throw(runtime_error("Cannot open the server on an invalid port or port 0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
//initialize the APIs
|
||||||
|
if (SDLNet_Init()) {
|
||||||
|
throw(runtime_error("Failed to initialize SDL_net"));
|
||||||
|
}
|
||||||
|
|
||||||
|
//initiate the remaining singletons
|
||||||
|
netUtil->Open(configUtil->Int("server.port"), sizeof(Packet));
|
||||||
|
|
||||||
|
//create the threads
|
||||||
|
beginQueueThread();
|
||||||
|
|
||||||
|
//output the server information
|
||||||
|
cout << configUtil->String("server.name") << endl;
|
||||||
|
cout << "Open on port " << configUtil->String("server.port") << endl;
|
||||||
|
|
||||||
|
//disable this for debugging
|
||||||
|
running = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerApplication::Proc() {
|
||||||
|
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 {
|
||||||
while(network.Receive()) {
|
//process all packets on the network queue
|
||||||
//get the packet
|
while(HandlePacket(popNetworkPacket()));
|
||||||
deserialize(&packet, network.GetInData());
|
|
||||||
//cache the source address
|
|
||||||
packet.meta.srcAddress = network.GetInPacket()->address;
|
|
||||||
//we need to go deeper
|
|
||||||
HandlePacket(packet);
|
|
||||||
}
|
}
|
||||||
//give the computer a break
|
catch(exception& e) {
|
||||||
|
//handle any errors
|
||||||
|
cerr << "Network Error: " << e.what() << endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//get the time since last update
|
||||||
|
delta = Clock::now() - lastTick;
|
||||||
|
lastTick = Clock::now();
|
||||||
|
|
||||||
|
//update the world
|
||||||
|
UpdateWorld(double(delta.count()) / Clock::duration::period::den);
|
||||||
|
|
||||||
|
//give the machine a break
|
||||||
SDL_Delay(10);
|
SDL_Delay(10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerApplication::Quit() {
|
void ServerApplication::Quit() {
|
||||||
cout << "Shutting down" << endl;
|
//close the threads
|
||||||
//empty the members
|
endQueueThread();
|
||||||
mapPager.UnloadAll();
|
|
||||||
//TODO: player manager
|
|
||||||
//TODO: client manager
|
|
||||||
|
|
||||||
//APIs
|
//clean up the singletons
|
||||||
lua_close(luaState);
|
netUtil->Close();
|
||||||
sqlite3_close_v2(database);
|
|
||||||
network.Close();
|
//deinitialize the APIs
|
||||||
SDLNet_Quit();
|
SDLNet_Quit();
|
||||||
SDL_Quit();
|
|
||||||
cout << "Shutdown finished" << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//Define the uber switch
|
//Game loop
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
void ServerApplication::HandlePacket(NetworkPacket packet) {
|
void ServerApplication::UpdateWorld(double delta) {
|
||||||
switch(packet.meta.type) {
|
//the recalc here each loop is a stopgap, see issue #9 for details
|
||||||
case NetworkPacket::Type::BROADCAST_REQUEST:
|
for (auto& it : players) {
|
||||||
HandleBroadcastRequest(packet);
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
//Network loop
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
|
int ServerApplication::HandlePacket(Packet p) {
|
||||||
|
switch(p.meta.type) {
|
||||||
|
case Packet::Type::NONE:
|
||||||
|
//DO NOTHING
|
||||||
|
return 0;
|
||||||
break;
|
break;
|
||||||
case NetworkPacket::Type::JOIN_REQUEST:
|
case Packet::Type::PING:
|
||||||
HandleJoinRequest(packet);
|
//quick pong
|
||||||
|
p.meta.type = Packet::Type::PONG;
|
||||||
|
netUtil->Send(&p.meta.address, &p, sizeof(Packet));
|
||||||
break;
|
break;
|
||||||
case NetworkPacket::Type::DISCONNECT:
|
case Packet::Type::PONG:
|
||||||
HandleDisconnect(packet);
|
//
|
||||||
break;
|
break;
|
||||||
case NetworkPacket::Type::SYNCHRONIZE:
|
case Packet::Type::BROADCAST_REQUEST:
|
||||||
HandleSynchronize(packet);
|
HandleBroadcast(p);
|
||||||
break;
|
break;
|
||||||
case NetworkPacket::Type::SHUTDOWN:
|
// case PacketType::BROADCAST_RESPONSE:
|
||||||
HandleShutdown(packet);
|
// //
|
||||||
|
// break;
|
||||||
|
case Packet::Type::JOIN_REQUEST:
|
||||||
|
HandleConnection(p);
|
||||||
break;
|
break;
|
||||||
case NetworkPacket::Type::PLAYER_NEW:
|
// case PacketType::JOIN_RESPONSE:
|
||||||
HandlePlayerNew(packet);
|
// //
|
||||||
|
// break;
|
||||||
|
case Packet::Type::DISCONNECT:
|
||||||
|
HandleDisconnection(p);
|
||||||
break;
|
break;
|
||||||
case NetworkPacket::Type::PLAYER_DELETE:
|
case Packet::Type::SYNCHRONIZE:
|
||||||
HandlePlayerDelete(packet);
|
SynchronizeEverything(p);
|
||||||
break;
|
break;
|
||||||
case NetworkPacket::Type::PLAYER_UPDATE:
|
case Packet::Type::PLAYER_NEW:
|
||||||
HandlePlayerUpdate(packet);
|
AddPlayer(p);
|
||||||
|
RelayPacket(p);
|
||||||
break;
|
break;
|
||||||
case NetworkPacket::Type::REGION_REQUEST:
|
case Packet::Type::PLAYER_DELETE:
|
||||||
HandleRegionRequest(packet);
|
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::SynchronizeEverything(Packet& sync) {
|
||||||
//Handle various network input
|
//send all known data to this client
|
||||||
//-------------------------
|
//TODO multithreading?
|
||||||
|
|
||||||
void ServerApplication::HandleBroadcastRequest(NetworkPacket packet) {
|
//all players
|
||||||
//send back the server's metadata
|
Packet p;
|
||||||
packet.meta.type = NetworkPacket::Type::BROADCAST_RESPONSE;
|
p.meta.type = Packet::Type::PLAYER_UPDATE;
|
||||||
//TODO: version info
|
for (auto& it : players) {
|
||||||
snprintf(packet.serverInfo.name, PACKET_STRING_SIZE, "%s", config["server.name"].c_str());
|
p.meta.clientIndex = it.second.clientIndex;
|
||||||
//TODO: player count
|
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
|
||||||
serialize(&packet, buffer);
|
|
||||||
network.Send(&packet.meta.srcAddress, buffer, PACKET_BUFFER_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerApplication::HandleJoinRequest(NetworkPacket packet) {
|
p.playerInfo.index = it.second.index;
|
||||||
//register the new client
|
snprintf(p.playerInfo.handle, PACKET_STRING_SIZE, "%s", it.second.handle.c_str());
|
||||||
ClientEntry c;
|
snprintf(p.playerInfo.avatar, PACKET_STRING_SIZE, "%s", it.second.avatar.c_str());
|
||||||
c.address = packet.meta.srcAddress;
|
p.playerInfo.position = it.second.position;
|
||||||
clientMap[clientCounter] = c;
|
p.playerInfo.motion = it.second.motion;
|
||||||
|
|
||||||
//send the client their info
|
netUtil->Send(&clients[sync.meta.clientIndex].address, &p, sizeof(Packet));
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
|
||||||
|
|
||||||
packet.meta.type = NetworkPacket::Type::JOIN_RESPONSE;
|
|
||||||
packet.clientInfo.index = clientCounter;
|
|
||||||
serialize(&packet, buffer);
|
|
||||||
|
|
||||||
network.Send(&clientMap[clientCounter].address, buffer, PACKET_BUFFER_SIZE);
|
|
||||||
|
|
||||||
//finished this routine
|
|
||||||
clientCounter++;
|
|
||||||
cout << "Connect, total: " << clientMap.size() << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerApplication::HandleDisconnect(NetworkPacket packet) {
|
|
||||||
//disconnect the specified client
|
|
||||||
//TODO: authenticate who is disconnecting/kicking
|
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
|
||||||
serialize(&packet, buffer);
|
|
||||||
network.Send(&clientMap[packet.clientInfo.index].address, buffer, PACKET_BUFFER_SIZE);
|
|
||||||
clientMap.erase(packet.clientInfo.index);
|
|
||||||
|
|
||||||
//delete players from all clients
|
|
||||||
NetworkPacket delPacket;
|
|
||||||
delPacket.meta.type = NetworkPacket::Type::PLAYER_DELETE;
|
|
||||||
|
|
||||||
erase_if(playerMap, [&](std::pair<int, PlayerEntry> it) -> bool {
|
|
||||||
//find the internal players to delete
|
|
||||||
if (it.second.clientIndex == packet.clientInfo.index) {
|
|
||||||
delPacket.playerInfo.playerIndex = it.first;
|
|
||||||
//send the delete player command to all clients
|
|
||||||
PumpPacket(delPacket);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
//finished this routine
|
|
||||||
cout << "Disconnect, total: " << clientMap.size() << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerApplication::HandleSynchronize(NetworkPacket packet) {
|
|
||||||
//send all the server's data to this client
|
|
||||||
//TODO: compensate for large distances
|
|
||||||
NetworkPacket newPacket;
|
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
|
||||||
|
|
||||||
//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;
|
|
||||||
serialize(&newPacket, buffer);
|
|
||||||
network.Send(&clientMap[packet.clientInfo.index].address, buffer, PACKET_BUFFER_SIZE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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));
|
||||||
|
|
||||||
//finished this routine
|
|
||||||
cout << "Shutdown signal accepted" << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerApplication::HandlePlayerNew(NetworkPacket packet) {
|
void ServerApplication::HandleConnection(Packet& request) {
|
||||||
//create the new player object
|
//create the entries
|
||||||
PlayerEntry newPlayer;
|
ClientEntry newClient = {
|
||||||
newPlayer.clientIndex = packet.playerInfo.clientIndex;
|
uniqueIndex++,
|
||||||
newPlayer.mapIndex = 0;
|
request.meta.address
|
||||||
newPlayer.handle = packet.playerInfo.handle;
|
};
|
||||||
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, PlayerEntry> 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"));
|
||||||
}
|
|
||||||
|
|
||||||
//server is the slave to the clients, but only for now
|
|
||||||
playerMap[packet.playerInfo.playerIndex].position = packet.playerInfo.position;
|
|
||||||
playerMap[packet.playerInfo.playerIndex].motion = packet.playerInfo.motion;
|
|
||||||
|
|
||||||
PumpPacket(packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerApplication::HandleRegionRequest(NetworkPacket packet) {
|
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
|
||||||
packet.meta.type = NetworkPacket::Type::REGION_CONTENT;
|
|
||||||
packet.regionInfo.region = mapPager.GetRegion(packet.regionInfo.x, packet.regionInfo.y);
|
|
||||||
serialize(&packet, buffer);
|
|
||||||
network.Send(&packet.meta.srcAddress, buffer, PACKET_BUFFER_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerApplication::PumpPacket(NetworkPacket packet) {
|
|
||||||
//I don't really like this, but it'll do for now
|
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
|
||||||
serialize(&packet, buffer);
|
|
||||||
for (auto& it : clientMap) {
|
|
||||||
network.Send(&it.second.address, buffer, PACKET_BUFFER_SIZE);
|
|
||||||
}
|
}
|
||||||
|
players[p.playerInfo.index].position = p.playerInfo.position;
|
||||||
|
players[p.playerInfo.index].motion = p.playerInfo.motion;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,90 +22,73 @@
|
|||||||
#ifndef SERVERAPPLICATION_HPP_
|
#ifndef SERVERAPPLICATION_HPP_
|
||||||
#define SERVERAPPLICATION_HPP_
|
#define SERVERAPPLICATION_HPP_
|
||||||
|
|
||||||
//maps
|
#include "packet.hpp"
|
||||||
#include "map_generator.hpp"
|
#include "singleton.hpp"
|
||||||
#include "map_file_format.hpp"
|
#include "network_queue.hpp"
|
||||||
#include "region_pager.hpp"
|
|
||||||
|
|
||||||
//networking
|
#include "config_Utility.hpp"
|
||||||
#include "network_packet.hpp"
|
|
||||||
#include "udp_network_utility.hpp"
|
#include "udp_network_utility.hpp"
|
||||||
#include "serial.hpp"
|
|
||||||
|
|
||||||
//common
|
|
||||||
#include "config_utility.hpp"
|
|
||||||
#include "vector2.hpp"
|
#include "vector2.hpp"
|
||||||
|
|
||||||
//APIs
|
#include "SDL/SDL_thread.h"
|
||||||
#include "lua/lua.hpp"
|
|
||||||
#include "sqlite3/sqlite3.h"
|
|
||||||
#include "SDL/SDL.h"
|
|
||||||
|
|
||||||
//STL
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
struct ClientEntry {
|
struct ClientEntry {
|
||||||
|
int index;
|
||||||
IPaddress address;
|
IPaddress address;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PlayerEntry {
|
struct PlayerEntry {
|
||||||
|
int index;
|
||||||
int clientIndex;
|
int clientIndex;
|
||||||
int mapIndex;
|
|
||||||
std::string handle;
|
std::string handle;
|
||||||
std::string avatar;
|
std::string avatar;
|
||||||
Vector2 position;
|
Vector2 position;
|
||||||
Vector2 motion;
|
Vector2 motion;
|
||||||
};
|
};
|
||||||
|
|
||||||
//The main application class
|
|
||||||
class ServerApplication {
|
class ServerApplication {
|
||||||
public:
|
public:
|
||||||
//standard functions
|
ServerApplication();
|
||||||
ServerApplication() = default;
|
~ServerApplication();
|
||||||
~ServerApplication() = default;
|
void Init();
|
||||||
|
void Proc();
|
||||||
void Init(int argc, char** argv);
|
|
||||||
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 HandleRegionRequest(NetworkPacket);
|
|
||||||
|
|
||||||
void PumpPacket(NetworkPacket);
|
void SynchronizeEverything(Packet&);
|
||||||
|
|
||||||
//maps
|
void HandleBroadcast(Packet&);
|
||||||
RegionPager<LuaGenerator, LuaFormat> mapPager;
|
void HandleConnection(Packet&);
|
||||||
|
void HandleDisconnection(Packet&);
|
||||||
|
|
||||||
//networking
|
void AddPlayer(Packet&);
|
||||||
UDPNetworkUtility network;
|
void RemovePlayer(Packet&);
|
||||||
|
void UpdatePlayer(Packet&);
|
||||||
|
|
||||||
//database
|
//services
|
||||||
sqlite3* database = nullptr;
|
ConfigUtility* configUtil = Singleton<ConfigUtility>::Get();
|
||||||
|
UDPNetworkUtility* netUtil = Singleton<UDPNetworkUtility>::Get();
|
||||||
|
|
||||||
//lua
|
//members
|
||||||
lua_State* luaState = nullptr;
|
std::map<int, ClientEntry> clients;
|
||||||
|
std::map<int, PlayerEntry> players;
|
||||||
|
|
||||||
//misc
|
bool running = false;
|
||||||
bool running = true;
|
|
||||||
ConfigUtility config;
|
|
||||||
|
|
||||||
std::map<int, ClientEntry> clientMap;
|
int uniqueIndex = 0;
|
||||||
std::map<int, PlayerEntry> playerMap;
|
|
||||||
|
|
||||||
int clientCounter = 0;
|
|
||||||
int playerCounter = 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+=. .. ../map
|
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
|
||||||
|
|
||||||