diff --git a/client/character.hpp b/client/character.hpp index ca2d9a4..bde4268 100644 --- a/client/character.hpp +++ b/client/character.hpp @@ -25,6 +25,7 @@ //components #include "character_defines.hpp" #include "vector2.hpp" +#include "bounding_box.hpp" #include "statistics.hpp" //graphics @@ -64,8 +65,8 @@ public: Vector2 GetOrigin() const { return origin; } Vector2 SetMotion(Vector2 v) { return motion = v; } Vector2 GetMotion() const { return motion; } - Vector2 SetBounds(Vector2 v) { return bounds = v; } - Vector2 GetBounds() const { return bounds; } + BoundingBox SetBounds(BoundingBox b) { return bounds = b; } + BoundingBox GetBounds() { return bounds; } private: //graphics @@ -84,7 +85,7 @@ private: //position Vector2 origin = {0.0,0.0}; Vector2 motion = {0.0,0.0}; - Vector2 bounds = {CHARACTER_BOUNDS_WIDTH,CHARACTER_BOUNDS_HEIGHT}; + BoundingBox bounds; }; //tmp diff --git a/client/client_application.cpp b/client/client_application.cpp index 991cfd6..d50dcd2 100644 --- a/client/client_application.cpp +++ b/client/client_application.cpp @@ -22,6 +22,7 @@ #include "client_application.hpp" #include "serial.hpp" +#include "config_utility.hpp" #include #include @@ -48,6 +49,7 @@ void ClientApplication::Init(int argc, char** argv) { std::cout << "Beginning " << argv[0] << std::endl; //load the prerequisites + ConfigUtility& config = ConfigUtility::GetSingleton(); config.Load("rsc\\config.cfg"); //------------------------- @@ -165,25 +167,25 @@ void ClientApplication::LoadScene(SceneList sceneIndex) { //add scene creation calls here case SceneList::FIRST: case SceneList::SPLASHSCREEN: - activeScene = new SplashScreen(&config); + activeScene = new SplashScreen(); break; case SceneList::MAINMENU: - activeScene = new MainMenu(&config); + activeScene = new MainMenu(); break; case SceneList::OPTIONSMENU: - activeScene = new OptionsMenu(&config); + activeScene = new OptionsMenu(); break; case SceneList::LOBBYMENU: - activeScene = new LobbyMenu(&config, &network, &clientIndex, &accountIndex); + activeScene = new LobbyMenu(&network, &clientIndex, &accountIndex); break; case SceneList::INWORLD: - activeScene = new InWorld(&config, &network, &clientIndex, &accountIndex, &characterIndex, &characterMap); + activeScene = new InWorld(&network, &clientIndex, &accountIndex, &characterIndex, &characterMap); break; case SceneList::INCOMBAT: - activeScene = new InCombat(&config, &network, &clientIndex, &accountIndex, &characterIndex, &characterMap); + activeScene = new InCombat(&network, &clientIndex, &accountIndex, &characterIndex, &characterMap); break; case SceneList::CLEANUP: - activeScene = new CleanUp(&config, &network, &clientIndex, &accountIndex, &characterIndex, &characterMap); + activeScene = new CleanUp(&network, &clientIndex, &accountIndex, &characterIndex, &characterMap); break; default: throw(std::logic_error("Failed to recognize the scene index")); diff --git a/client/client_application.hpp b/client/client_application.hpp index 2efb742..eea274f 100644 --- a/client/client_application.hpp +++ b/client/client_application.hpp @@ -25,22 +25,26 @@ #include "scene_list.hpp" #include "base_scene.hpp" -#include "config_utility.hpp" #include "udp_network_utility.hpp" #include "character.hpp" +#include "singleton.hpp" + #include -class ClientApplication { +class ClientApplication: public Singleton { public: - ClientApplication() = default; - ~ClientApplication() = default; - + //public methods void Init(int argc, char** argv); void Proc(); void Quit(); private: + friend Singleton; + + ClientApplication() = default; + ~ClientApplication() = default; + //Private access members void LoadScene(SceneList sceneIndex); void UnloadScene(); @@ -48,7 +52,6 @@ private: BaseScene* activeScene = nullptr; //shared parameters - ConfigUtility config; UDPNetworkUtility network; int clientIndex = -1; int accountIndex = -1; diff --git a/client/main.cpp b/client/main.cpp index 156adff..57154b6 100644 --- a/client/main.cpp +++ b/client/main.cpp @@ -21,6 +21,9 @@ */ #include "client_application.hpp" +//singletons +#include "config_utility.hpp" + #include #include @@ -28,14 +31,23 @@ using namespace std; int main(int argc, char** argv) { try { - ClientApplication app; + //create the singletons + ClientApplication::Create(); + ConfigUtility::Create(); + + //call the server's routines + ClientApplication& app = ClientApplication::GetSingleton(); app.Init(argc, argv); app.Proc(); app.Quit(); + + //delete the singletons + ConfigUtility::Delete(); + ClientApplication::Delete(); } catch(exception& e) { cerr << "Fatal exception thrown: " << e.what() << endl; return 1; } return 0; -} +} \ No newline at end of file diff --git a/client/makefile b/client/makefile index 97d8949..f318d52 100644 --- a/client/makefile +++ b/client/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. scenes ../common/gameplay ../common/graphics ../common/map ../common/network ../common/network/packet ../common/network/serial ../common/ui ../common/utilities +INCLUDES+=. scenes ../common/debugging ../common/gameplay ../common/graphics ../common/map ../common/network ../common/network/packet ../common/network/serial ../common/ui ../common/utilities LIBS+=client.a ../libcommon.a -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL -llua CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) diff --git a/client/scenes/clean_up.cpp b/client/scenes/clean_up.cpp index 42ab69c..87846d5 100644 --- a/client/scenes/clean_up.cpp +++ b/client/scenes/clean_up.cpp @@ -22,6 +22,7 @@ #include "clean_up.hpp" #include "channels.hpp" +#include "config_utility.hpp" #include @@ -30,20 +31,20 @@ //------------------------- CleanUp::CleanUp( - ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex, int* const argAccountIndex, int* const argCharacterIndex, CharacterMap* argCharacterMap ): - config(*argConfig), network(*argNetwork), clientIndex(*argClientIndex), accountIndex(*argAccountIndex), characterIndex(*argCharacterIndex), characterMap(*argCharacterMap) { + ConfigUtility& config = ConfigUtility::GetSingleton(); + //setup the utility objects image.LoadSurface(config["dir.interface"] + "button_menu.bmp"); image.SetClipH(image.GetClipH()/3); diff --git a/client/scenes/clean_up.hpp b/client/scenes/clean_up.hpp index 5586f5c..3ba76ce 100644 --- a/client/scenes/clean_up.hpp +++ b/client/scenes/clean_up.hpp @@ -31,7 +31,6 @@ #include "button.hpp" //common -#include "config_utility.hpp" #include "frame_rate.hpp" #include "character.hpp" @@ -46,7 +45,6 @@ class CleanUp : public BaseScene { public: //Public access members CleanUp( - ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex, int* const argAccountIndex, @@ -70,7 +68,6 @@ protected: void KeyUp(SDL_KeyboardEvent const&); //shared parameters - ConfigUtility& config; UDPNetworkUtility& network; int& clientIndex; int& accountIndex; diff --git a/client/scenes/in_combat.cpp b/client/scenes/in_combat.cpp index 68c1bec..358bd08 100644 --- a/client/scenes/in_combat.cpp +++ b/client/scenes/in_combat.cpp @@ -23,6 +23,7 @@ #include "channels.hpp" #include "utility.hpp" +#include "config_utility.hpp" #include @@ -31,14 +32,12 @@ //------------------------- InCombat::InCombat( - ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex, int* const argAccountIndex, int* const argCharacterIndex, CharacterMap* argCharacterMap ): - config(*argConfig), network(*argNetwork), clientIndex(*argClientIndex), accountIndex(*argAccountIndex), diff --git a/client/scenes/in_combat.hpp b/client/scenes/in_combat.hpp index 6a84851..2f5cd20 100644 --- a/client/scenes/in_combat.hpp +++ b/client/scenes/in_combat.hpp @@ -31,7 +31,6 @@ #include "button.hpp" //common -#include "config_utility.hpp" #include "frame_rate.hpp" #include "character.hpp" @@ -43,7 +42,6 @@ class InCombat : public BaseScene { public: //Public access members InCombat( - ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex, int* const argAccountIndex, @@ -79,7 +77,6 @@ protected: void RequestShutdown(); //shared parameters - ConfigUtility& config; UDPNetworkUtility& network; int& clientIndex; int& accountIndex; diff --git a/client/scenes/in_world.cpp b/client/scenes/in_world.cpp index 4f997a0..dac3bce 100644 --- a/client/scenes/in_world.cpp +++ b/client/scenes/in_world.cpp @@ -23,6 +23,7 @@ #include "channels.hpp" #include "utility.hpp" +#include "config_utility.hpp" #include #include @@ -34,20 +35,20 @@ //------------------------- InWorld::InWorld( - ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex, int* const argAccountIndex, int* const argCharacterIndex, CharacterMap* argCharacterMap ): - config(*argConfig), network(*argNetwork), clientIndex(*argClientIndex), accountIndex(*argAccountIndex), characterIndex(*argCharacterIndex), characterMap(*argCharacterMap) { + ConfigUtility& config = ConfigUtility::GetSingleton(); + //setup the utility objects buttonImage.LoadSurface(config["dir.interface"] + "button_menu.bmp"); buttonImage.SetClipH(buttonImage.GetClipH()/3); @@ -71,7 +72,8 @@ InWorld::InWorld( //load the tilesheet //TODO: add the tilesheet to the map system? - tileSheet.Load(config["dir.tilesets"] + "terrain.bmp", 12, 15); + //TODO: Tile size and tile sheet should be loaded elsewhere + tileSheet.Load(config["dir.tilesets"] + "terrain.bmp", 32, 32); //request a sync RequestSynchronize(); @@ -105,16 +107,41 @@ void InWorld::Update(double delta) { it.second.Update(delta); } - //TODO: Check collisions here - - //update the camera - if(localCharacter) { - camera.x = localCharacter->GetOrigin().x - camera.marginX; - camera.y = localCharacter->GetOrigin().y - camera.marginY; - } - //check the map UpdateMap(); + + //skip the rest + if (!localCharacter) { + return; + } + + //check for collisions with the map + BoundingBox wallBounds = {0, 0, tileSheet.GetTileW(), tileSheet.GetTileH()}; + const int xCount = localCharacter->GetBounds().w / wallBounds.w + 1; + const int yCount = localCharacter->GetBounds().h / wallBounds.h + 1; + + for (int i = -1; i <= xCount; ++i) { + for (int j = -1; j <= yCount; ++j) { + //set the wall's position + wallBounds.x = wallBounds.w * i + snapToBase((double)wallBounds.w, localCharacter->GetOrigin().x); + wallBounds.y = wallBounds.h * j + snapToBase((double)wallBounds.h, localCharacter->GetOrigin().y); + + if (!regionPager.GetSolid(wallBounds.x / wallBounds.w, wallBounds.y / wallBounds.h)) { + continue; + } + + if ((localCharacter->GetOrigin() + localCharacter->GetBounds()).CheckOverlap(wallBounds)) { + localCharacter->SetOrigin(localCharacter->GetOrigin() - (localCharacter->GetMotion() * delta)); + localCharacter->SetMotion({0,0}); + localCharacter->CorrectSprite(); + SendPlayerUpdate(); + } + } + } + + //update the camera + camera.x = localCharacter->GetOrigin().x - camera.marginX; + camera.y = localCharacter->GetOrigin().y - camera.marginY; } void InWorld::FrameEnd() { @@ -276,10 +303,11 @@ void InWorld::HandleCharacterNew(CharacterPacket* const argPacket) { newCharacter.SetHandle(argPacket->handle); newCharacter.SetAvatar(argPacket->avatar); - newCharacter.GetSprite()->LoadSurface(config["dir.sprites"] + newCharacter.GetAvatar(), 4, 4); + newCharacter.GetSprite()->LoadSurface(ConfigUtility::GetSingleton()["dir.sprites"] + newCharacter.GetAvatar(), 4, 4); newCharacter.SetOrigin(argPacket->origin); newCharacter.SetMotion(argPacket->motion); + newCharacter.SetBounds({0, 16, 32, 32}); //TODO: magic numbers, fix this (*newCharacter.GetStats()) = argPacket->stats; diff --git a/client/scenes/in_world.hpp b/client/scenes/in_world.hpp index 34ce942..8dddfdf 100644 --- a/client/scenes/in_world.hpp +++ b/client/scenes/in_world.hpp @@ -35,7 +35,6 @@ #include "tile_sheet.hpp" //common -#include "config_utility.hpp" #include "frame_rate.hpp" #include "character.hpp" @@ -50,7 +49,6 @@ class InWorld : public BaseScene { public: //Public access members InWorld( - ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex, int* const argAccountIndex, @@ -94,7 +92,6 @@ protected: void UpdateMap(); //shared parameters - ConfigUtility& config; UDPNetworkUtility& network; int& clientIndex; int& accountIndex; diff --git a/client/scenes/lobby_menu.cpp b/client/scenes/lobby_menu.cpp index f4b5e32..2e71a89 100644 --- a/client/scenes/lobby_menu.cpp +++ b/client/scenes/lobby_menu.cpp @@ -31,12 +31,10 @@ //------------------------- LobbyMenu::LobbyMenu( - ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex, int* const argAccountIndex ): - config(*argConfig), network(*argNetwork), clientIndex(*argClientIndex), accountIndex(*argAccountIndex) diff --git a/client/scenes/lobby_menu.hpp b/client/scenes/lobby_menu.hpp index a27c1a9..96afaa0 100644 --- a/client/scenes/lobby_menu.hpp +++ b/client/scenes/lobby_menu.hpp @@ -41,7 +41,6 @@ class LobbyMenu : public BaseScene { public: //Public access members LobbyMenu( - ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex, int* const argAccountIndex @@ -68,7 +67,7 @@ protected: void HandleJoinResponse(ClientPacket* const); //shared parameters - ConfigUtility& config; + ConfigUtility& config = ConfigUtility::GetSingleton(); UDPNetworkUtility& network; int& clientIndex; int& accountIndex; diff --git a/client/scenes/main_menu.cpp b/client/scenes/main_menu.cpp index 735e2fb..ca82ef8 100644 --- a/client/scenes/main_menu.cpp +++ b/client/scenes/main_menu.cpp @@ -21,13 +21,15 @@ */ #include "main_menu.hpp" +#include "config_utility.hpp" + //------------------------- //Public access members //------------------------- -MainMenu::MainMenu(ConfigUtility* const argConfig): - config(*argConfig) -{ +MainMenu::MainMenu() { + ConfigUtility& config = ConfigUtility::GetSingleton(); + //setup the utility objects image.LoadSurface(config["dir.interface"] + "button_menu.bmp"); image.SetClipH(image.GetClipH()/3); @@ -101,6 +103,7 @@ void MainMenu::MouseButtonDown(SDL_MouseButtonEvent const& button) { } void MainMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) { + //TODO: Buttons should only register as "selected" when the left button is used if (startButton.MouseButtonUp(button) == Button::State::HOVER) { SetNextScene(SceneList::LOBBYMENU); } diff --git a/client/scenes/main_menu.hpp b/client/scenes/main_menu.hpp index 3816482..2dec3ae 100644 --- a/client/scenes/main_menu.hpp +++ b/client/scenes/main_menu.hpp @@ -24,7 +24,6 @@ #include "base_scene.hpp" -#include "config_utility.hpp" #include "image.hpp" #include "raster_font.hpp" #include "button.hpp" @@ -32,7 +31,7 @@ class MainMenu : public BaseScene { public: //Public access members - MainMenu(ConfigUtility* const); + MainMenu(); ~MainMenu(); protected: @@ -49,9 +48,6 @@ protected: void KeyDown(SDL_KeyboardEvent const&); void KeyUp(SDL_KeyboardEvent const&); - //shared parameters - ConfigUtility& config; - //members Image image; RasterFont font; diff --git a/client/scenes/options_menu.cpp b/client/scenes/options_menu.cpp index 19b3b9e..4a991f7 100644 --- a/client/scenes/options_menu.cpp +++ b/client/scenes/options_menu.cpp @@ -21,13 +21,15 @@ */ #include "options_menu.hpp" +#include "config_utility.hpp" + //------------------------- //Public access members //------------------------- -OptionsMenu::OptionsMenu(ConfigUtility* const argConfig): - config(*argConfig) -{ +OptionsMenu::OptionsMenu() { + ConfigUtility& config = ConfigUtility::GetSingleton(); + //setup the utility objects image.LoadSurface(config["dir.interface"] + "button_menu.bmp"); image.SetClipH(image.GetClipH()/3); diff --git a/client/scenes/options_menu.hpp b/client/scenes/options_menu.hpp index 37e4e64..8570644 100644 --- a/client/scenes/options_menu.hpp +++ b/client/scenes/options_menu.hpp @@ -24,7 +24,6 @@ #include "base_scene.hpp" -#include "config_utility.hpp" #include "image.hpp" #include "raster_font.hpp" #include "button.hpp" @@ -33,7 +32,7 @@ class OptionsMenu : public BaseScene { public: //Public access members - OptionsMenu(ConfigUtility* const); + OptionsMenu(); ~OptionsMenu(); protected: @@ -50,9 +49,6 @@ protected: void KeyDown(SDL_KeyboardEvent const&); void KeyUp(SDL_KeyboardEvent const&); - //shared parameters - ConfigUtility& config; - //members Image image; RasterFont font; diff --git a/client/scenes/splash_screen.cpp b/client/scenes/splash_screen.cpp index a363a2c..2c3b233 100644 --- a/client/scenes/splash_screen.cpp +++ b/client/scenes/splash_screen.cpp @@ -21,14 +21,14 @@ */ #include "splash_screen.hpp" +#include "config_utility.hpp" + //------------------------- //Public access members //------------------------- -SplashScreen::SplashScreen(ConfigUtility* const argConfig): - config(*argConfig) -{ - logo.LoadSurface(config["dir.logos"] + "krstudios.bmp"); +SplashScreen::SplashScreen() { + logo.LoadSurface(ConfigUtility::GetSingleton()["dir.logos"] + "krstudios.bmp"); startTick = std::chrono::steady_clock::now(); } diff --git a/client/scenes/splash_screen.hpp b/client/scenes/splash_screen.hpp index 2b2000b..9d55c0c 100644 --- a/client/scenes/splash_screen.hpp +++ b/client/scenes/splash_screen.hpp @@ -24,7 +24,6 @@ #include "base_scene.hpp" -#include "config_utility.hpp" #include "image.hpp" #include @@ -32,7 +31,7 @@ class SplashScreen : public BaseScene { public: //Public access members - SplashScreen(ConfigUtility* const); + SplashScreen(); ~SplashScreen(); protected: @@ -40,9 +39,6 @@ protected: void Update(double delta); void Render(SDL_Surface* const); - //shared parameters - ConfigUtility& config; - //members std::chrono::steady_clock::time_point startTick; Image logo; diff --git a/common/debugging/makefile b/common/debugging/makefile new file mode 100644 index 0000000..9013447 --- /dev/null +++ b/common/debugging/makefile @@ -0,0 +1,37 @@ +#config +INCLUDES+=. +LIBS+= +CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) + +#source +CXXSRC=$(wildcard *.cpp) + +#objects +OBJDIR=obj +OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.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 $@ $< + +clean: + $(RM) *.o *.a *.exe + +rebuild: clean all diff --git a/common/debugging/timer.cpp b/common/debugging/timer.cpp new file mode 100644 index 0000000..29d107a --- /dev/null +++ b/common/debugging/timer.cpp @@ -0,0 +1,45 @@ +/* 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 "timer.hpp" + +Timer::Timer(): start(Timer::Clock::now()) { + // +} + +Timer::Timer(std::string s): name(s), start(Timer::Clock::now()) { + // +} + +void Timer::Start() { + start = Clock::now(); +} + +void Timer::Stop() { + timeSpan = Clock::now() - start; +} + +std::ostream& operator<<(std::ostream& os, Timer& t) { + os << t.GetName() << ": "; + os << std::chrono::duration_cast(t.GetTime()).count(); + os << "ms"; + return os; +} diff --git a/common/debugging/timer.hpp b/common/debugging/timer.hpp new file mode 100644 index 0000000..dfafec9 --- /dev/null +++ b/common/debugging/timer.hpp @@ -0,0 +1,54 @@ +/* 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 TIMER_HPP_ +#define TIMER_HPP_ + +#include +#include +#include + +class Timer { +public: + typedef std::chrono::high_resolution_clock Clock; + + Timer(); + Timer(std::string s); + ~Timer() = default; + + inline void Start(); + inline void Stop(); + + //accessors and mutators + Clock::duration GetTime() { return timeSpan; } + + std::string SetName(std::string s) { return name = s; } + std::string GetName() { return name; } + +private: + std::string name; + Clock::time_point start; + Clock::duration timeSpan; +}; + +std::ostream& operator<<(std::ostream& os, Timer& t); + +#endif diff --git a/common/graphics/makefile b/common/graphics/makefile index afcde11..9013447 100644 --- a/common/graphics/makefile +++ b/common/graphics/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. ../map +INCLUDES+=. LIBS+= CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) diff --git a/common/makefile b/common/makefile index b670b7d..bdb1406 100644 --- a/common/makefile +++ b/common/makefile @@ -1,4 +1,5 @@ all: + $(MAKE) -C debugging $(MAKE) -C gameplay $(MAKE) -C graphics $(MAKE) -C map diff --git a/common/map/makefile b/common/map/makefile index 769709e..24e7779 100644 --- a/common/map/makefile +++ b/common/map/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. ../utilities +INCLUDES+=. ../graphics ../utilities LIBS+= CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) diff --git a/common/map/region_api.cpp b/common/map/region_api.cpp index 014a873..2fd3dbb 100644 --- a/common/map/region_api.cpp +++ b/common/map/region_api.cpp @@ -78,28 +78,27 @@ static int getDepth(lua_State* L) { return 1; } -static int onLoad(lua_State* L) { - //TODO: onLoad() +static int load(lua_State* L) { + //EMPTY lua_pushboolean(L, false); return 1; } -static int onSave(lua_State* L) { - //TODO: onSave() +static int save(lua_State* L) { + //EMPTY return 0; } -static int onCreate(lua_State* L) { - //TODO: onCreate() +static int create(lua_State* L) { + //EMPTY return 0; } -static int onUnload(lua_State* L) { - //TODO: onUnload() +static int unload(lua_State* L) { + //EMPTY return 0; } -//TODO: wrappers for the collision map static const luaL_Reg regionLib[] = { {"SetTile",setTile}, {"GetTile",getTile}, @@ -110,10 +109,10 @@ static const luaL_Reg regionLib[] = { {"GetWidth",getWidth}, {"GetHeight",getHeight}, {"GetDepth",getDepth}, - {"OnLoad",onLoad}, - {"OnSave",onSave}, - {"OnCreate",onCreate}, - {"OnUnload",onUnload}, + {"Load",load}, + {"Save",save}, + {"Create",create}, + {"Unload",unload}, {nullptr, nullptr} }; diff --git a/common/map/region_pager_api.cpp b/common/map/region_pager_api.cpp index 40c4d76..3932421 100644 --- a/common/map/region_pager_api.cpp +++ b/common/map/region_pager_api.cpp @@ -24,10 +24,9 @@ #include "region_pager_lua.hpp" #include "region.hpp" -#include #include -//DOCS: These functions are just wrappers for the RegionPagerLua class +//DOCS: These glue functions simply wrap RegionPagerLua's methods static int setTile(lua_State* L) { RegionPagerLua* pager = reinterpret_cast(lua_touserdata(L, 1)); @@ -64,20 +63,6 @@ static int getRegion(lua_State* L) { return 1; } -static int setDirectory(lua_State* L) { - RegionPagerLua* pager = reinterpret_cast(lua_touserdata(L, 1)); - std::string s = pager->SetDirectory(lua_tostring(L, 2)); - lua_pushstring(L, s.c_str()); - return 1; -} - -static int getDirectory(lua_State* L) { - RegionPagerLua* pager = reinterpret_cast(lua_touserdata(L, 1)); - std::string s = pager->GetDirectory(); - lua_pushstring(L, s.c_str()); - return 1; -} - static int loadRegion(lua_State* L) { RegionPagerLua* pager = reinterpret_cast(lua_touserdata(L, 1)); Region* region = pager->LoadRegion(lua_tointeger(L, 2), lua_tointeger(L, 3)); @@ -105,14 +90,12 @@ static int unloadRegion(lua_State* L) { return 0; } -static const luaL_Reg pagerlib[] = { +static const luaL_Reg regionPagerLib[] = { {"SetTile", setTile}, {"GetTile", getTile}, {"SetSolid", setSolid}, {"GetSolid", getSolid}, {"GetRegion", getRegion}, - {"SetDirectory", setDirectory}, - {"GetDirectory", getDirectory}, {"LoadRegion", loadRegion}, {"SaveRegion", saveRegion}, {"CreateRegion", createRegion}, @@ -121,6 +104,6 @@ static const luaL_Reg pagerlib[] = { }; LUAMOD_API int openRegionPagerAPI(lua_State* L) { - luaL_newlib(L, pagerlib); + luaL_newlib(L, regionPagerLib); return 1; } \ No newline at end of file diff --git a/common/map/region_pager_api.hpp b/common/map/region_pager_api.hpp index 466af61..3636c5a 100644 --- a/common/map/region_pager_api.hpp +++ b/common/map/region_pager_api.hpp @@ -19,8 +19,8 @@ * 3. This notice may not be removed or altered from any source * distribution. */ -#ifndef PAGERAPI_HPP_ -#define PAGERAPI_HPP_ +#ifndef REGIONPAGERAPI_HPP_ +#define REGIONPAGERAPI_HPP_ #include "lua/lua.hpp" diff --git a/common/map/region_pager_base.cpp b/common/map/region_pager_base.cpp index fbe633d..8c31df1 100644 --- a/common/map/region_pager_base.cpp +++ b/common/map/region_pager_base.cpp @@ -47,6 +47,9 @@ bool RegionPagerBase::GetSolid(int x, int y) { } Region* RegionPagerBase::GetRegion(int x, int y) { + x = snapToBase(REGION_WIDTH, x); + y = snapToBase(REGION_HEIGHT, y); + //get the region by various means Region* ptr = nullptr; ptr = FindRegion(x, y); diff --git a/common/map/region_pager_lua.cpp b/common/map/region_pager_lua.cpp index 85ea167..368f950 100644 --- a/common/map/region_pager_lua.cpp +++ b/common/map/region_pager_lua.cpp @@ -32,19 +32,18 @@ Region* RegionPagerLua::LoadRegion(int x, int y) { Region tmpRegion(x, y); //API hook - lua_getglobal(luaState, "Region"); - lua_getfield(luaState, -1, "OnLoad"); - lua_pushlightuserdata(luaState, &tmpRegion); - lua_pushstring(luaState, directory.c_str()); - if (lua_pcall(luaState, 2, 1, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); + lua_getglobal(lua, "Region"); + lua_getfield(lua, -1, "Load"); + lua_pushlightuserdata(lua, &tmpRegion); + if (lua_pcall(lua, 1, 1, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); } //success or failure - if (!lua_toboolean(luaState, -1)) { - lua_pop(luaState, 2); + if (!lua_toboolean(lua, -1)) { + lua_pop(lua, 2); return nullptr; } - lua_pop(luaState, 2); + lua_pop(lua, 2); regionList.push_front(tmpRegion); return ®ionList.front(); } @@ -54,14 +53,13 @@ Region* RegionPagerLua::SaveRegion(int x, int y) { Region* ptr = FindRegion(x, y); if (ptr) { //API hook - lua_getglobal(luaState, "Region"); - lua_getfield(luaState, -1, "OnSave"); - lua_pushlightuserdata(luaState, ptr); - lua_pushstring(luaState, directory.c_str()); - if (lua_pcall(luaState, 2, 0, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); + lua_getglobal(lua, "Region"); + lua_getfield(lua, -1, "Save"); + lua_pushlightuserdata(lua, ptr); + if (lua_pcall(lua, 1, 0, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); } - lua_pop(luaState, 1); + lua_pop(lua, 1); } return ptr; } @@ -75,30 +73,29 @@ Region* RegionPagerLua::CreateRegion(int x, int y) { Region tmpRegion(x, y); //API hook - lua_getglobal(luaState, "Region"); - lua_getfield(luaState, -1, "OnCreate"); - lua_pushlightuserdata(luaState, &tmpRegion); + lua_getglobal(lua, "Region"); + lua_getfield(lua, -1, "Create"); + lua_pushlightuserdata(lua, &tmpRegion); //TODO: parameters - if (lua_pcall(luaState, 1, 0, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); + if (lua_pcall(lua, 1, 0, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); } - lua_pop(luaState, 1); + lua_pop(lua, 1); regionList.push_front(tmpRegion); return ®ionList.front(); } void RegionPagerLua::UnloadRegion(int x, int y) { - lua_getglobal(luaState, "Region"); + lua_getglobal(lua, "Region"); regionList.remove_if([&](Region& region) -> bool { if (region.GetX() == x && region.GetY() == y) { //API hook - lua_getfield(luaState, -1, "OnUnload"); - lua_pushlightuserdata(luaState, ®ion); - lua_pushstring(luaState, directory.c_str()); - if (lua_pcall(luaState, 2, 0, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); + lua_getfield(lua, -1, "Unload"); + lua_pushlightuserdata(lua, ®ion); + if (lua_pcall(lua, 1, 0, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); } return true; @@ -106,22 +103,21 @@ void RegionPagerLua::UnloadRegion(int x, int y) { return false; }); - lua_pop(luaState, 1); + lua_pop(lua, 1); } void RegionPagerLua::UnloadAll() { - lua_getglobal(luaState, "Region"); + lua_getglobal(lua, "Region"); for (auto& it : regionList) { //API hook - lua_getfield(luaState, -1, "OnUnload"); - lua_pushlightuserdata(luaState, &it); - lua_pushstring(luaState, directory.c_str()); - if (lua_pcall(luaState, 2, 0, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); + lua_getfield(lua, -1, "Unload"); + lua_pushlightuserdata(lua, &it); + if (lua_pcall(lua, 1, 0, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); } } - lua_pop(luaState, 1); + lua_pop(lua, 1); regionList.clear(); } \ No newline at end of file diff --git a/common/map/region_pager_lua.hpp b/common/map/region_pager_lua.hpp index 9468a18..8543e2d 100644 --- a/common/map/region_pager_lua.hpp +++ b/common/map/region_pager_lua.hpp @@ -42,14 +42,10 @@ public: void UnloadAll() override; //accessors & mutators - std::string SetDirectory(std::string s) { return directory = s; } - std::string GetDirectory() { return directory; } - - lua_State* SetLuaState(lua_State* L) { return luaState = L; } - lua_State* GetLuaState() { return luaState; } + lua_State* SetLuaState(lua_State* L) { return lua = L; } + lua_State* GetLuaState() { return lua; } protected: - std::string directory; - lua_State* luaState = nullptr; + lua_State* lua = nullptr; }; #endif diff --git a/common/graphics/tile_sheet.cpp b/common/map/tile_sheet.cpp similarity index 73% rename from common/graphics/tile_sheet.cpp rename to common/map/tile_sheet.cpp index bb9a4cb..819d709 100644 --- a/common/graphics/tile_sheet.cpp +++ b/common/map/tile_sheet.cpp @@ -21,24 +21,24 @@ */ #include "tile_sheet.hpp" -void TileSheet::Load(std::string fname, int xc, int yc) { - XCount = xc; - YCount = yc; +void TileSheet::Load(std::string fname, int tileWidth, int tileHeight) { image.LoadSurface(fname); - image.SetClipW(image.GetClipW()/XCount); - image.SetClipH(image.GetClipH()/YCount); + image.SetClipW(tileWidth); + image.SetClipH(tileHeight); + xCount = image.GetSurface()->w / image.GetClipW(); + yCount = image.GetSurface()->h / image.GetClipH(); } void TileSheet::Unload() { image.FreeSurface(); - XCount = YCount = 0; + xCount = yCount = 0; } -void TileSheet::DrawTo(SDL_Surface* const dest, int x, int y, Region::type_t tile) { +void TileSheet::DrawTileTo(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.SetClipX((tile-1) % xCount * image.GetClipW()); + image.SetClipY((tile-1) / xCount * image.GetClipH()); image.DrawTo(dest, x, y); } @@ -50,8 +50,8 @@ void TileSheet::DrawRegionTo(SDL_Surface* const dest, Region* const region, int 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.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); diff --git a/common/graphics/tile_sheet.hpp b/common/map/tile_sheet.hpp similarity index 82% rename from common/graphics/tile_sheet.hpp rename to common/map/tile_sheet.hpp index 368fcec..f9bf8ea 100644 --- a/common/graphics/tile_sheet.hpp +++ b/common/map/tile_sheet.hpp @@ -31,24 +31,24 @@ class TileSheet { public: TileSheet() = default; - TileSheet(std::string f, int x, int y) { Load(f, x, y); } + TileSheet(std::string f, int w, int h) { Load(f, w, h); } ~TileSheet() = default; - void Load(std::string fname, int XCount, int YCount); + void Load(std::string fname, int tileWidth, int tileHeight); void Unload(); - void DrawTo(SDL_Surface* const dest, int x, int y, Region::type_t tile); + void DrawTileTo(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 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; + int xCount = 0, yCount = 0; }; #endif diff --git a/common/map/tile_sheet_api.cpp b/common/map/tile_sheet_api.cpp new file mode 100644 index 0000000..5ee280f --- /dev/null +++ b/common/map/tile_sheet_api.cpp @@ -0,0 +1,75 @@ +/* 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_api.hpp" + +#include "tile_sheet.hpp" + +static int load(lua_State* L) { + TileSheet* sheet = reinterpret_cast(lua_touserdata(L, 1)); + sheet->Load(lua_tostring(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4)); + return 0; +} + +static int unload(lua_State* L) { + TileSheet* sheet = reinterpret_cast(lua_touserdata(L, 1)); + sheet->Unload(); + return 0; +} + +static int getXCount(lua_State* L) { + TileSheet* sheet = reinterpret_cast(lua_touserdata(L, 1)); + lua_pushinteger(L, sheet->GetXCount()); + return 1; +} + +static int getYCount(lua_State* L) { + TileSheet* sheet = reinterpret_cast(lua_touserdata(L, 1)); + lua_pushinteger(L, sheet->GetYCount()); + return 1; +} + +static int getTileW(lua_State* L) { + TileSheet* sheet = reinterpret_cast(lua_touserdata(L, 1)); + lua_pushinteger(L, sheet->GetTileW()); + return 1; +} + +static int getTileH(lua_State* L) { + TileSheet* sheet = reinterpret_cast(lua_touserdata(L, 1)); + lua_pushinteger(L, sheet->GetTileH()); + return 1; +} + +static const luaL_Reg tileSheetLib[] = { + {"Load",load}, + {"Unload",unload}, + {"GetXCount",getXCount}, + {"GetYCount",getYCount}, + {"GetTileW",getTileW}, + {"GetTileH",getTileH}, + {nullptr, nullptr} +}; + +LUAMOD_API int openTileSheetAPI(lua_State* L) { + luaL_newlib(L, tileSheetLib); + return 1; +} \ No newline at end of file diff --git a/common/utilities/simple_rng.hpp b/common/map/tile_sheet_api.hpp similarity index 70% rename from common/utilities/simple_rng.hpp rename to common/map/tile_sheet_api.hpp index 52ca91b..0788535 100644 --- a/common/utilities/simple_rng.hpp +++ b/common/map/tile_sheet_api.hpp @@ -19,24 +19,12 @@ * 3. This notice may not be removed or altered from any source * distribution. */ -#ifndef SIMPLERNG_HPP_ -#define SIMPLERNG_HPP_ +#ifndef TILESHEETAPI_HPP_ +#define TILESHEETAPI_HPP_ -//a simple, stateless, random number generator -class SimpleRNG { -public: - SimpleRNG() { SetSeed(8891.0); } - SimpleRNG(double x) { SetSeed(x); } +#include "lua/lua.hpp" - double SetSeed(double s) { return seed = s; } - double GetSeed() { return seed; } +#define TORTUGA_TILE_SHEET_NAME "TileSheet" +LUAMOD_API int openTileSheetAPI(lua_State* L); - double operator()(double x) { - return (x + seed) * 11235.0 + 81321.0; - }; - -private: - double seed; -}; - -#endif \ No newline at end of file +#endif diff --git a/common/utilities/bounding_box.hpp b/common/utilities/bounding_box.hpp new file mode 100644 index 0000000..1d32887 --- /dev/null +++ b/common/utilities/bounding_box.hpp @@ -0,0 +1,77 @@ +/* Copyright: (c) Kayne Ruse 2013, 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 BOUNDINGBOX_HPP_ +#define BOUNDINGBOX_HPP_ + +#include +#include + +class BoundingBox { +public: + //This is explicitly a POD + int x, y; + int w, h; + + BoundingBox() = default; + BoundingBox(int i, int j, int k, int l): x(i), y(j), w(k), h(l) {}; + ~BoundingBox() = default; + BoundingBox& operator=(BoundingBox const&) = default; + + int Size() { + return std::max(w*h,0); + } + + bool CheckOverlap(BoundingBox rhs) { + return !( + x >= rhs.x + rhs.w || + y >= rhs.y + rhs.h || + rhs.x >= x + w || + rhs.y >= y + h); + } + + BoundingBox CalcOverlap(BoundingBox rhs) { + if (!CheckOverlap(rhs)) { + return {0, 0, 0, 0}; + } + BoundingBox ret; + ret.x = std::max(x, rhs.x); + ret.y = std::max(y, rhs.y); + ret.w = std::min(x+w, rhs.x+rhs.w) - ret.x; + ret.h = std::min(y+h, rhs.y+rhs.h) - ret.y; + return ret; + } +}; + +//This is explicitly a POD +static_assert(std::is_pod::value, "BoundingBox is not a POD"); + +#include "vector2.hpp" + +//operators +inline BoundingBox operator+(BoundingBox b, Vector2 v) { + return {b.x + (int)v.x, b.y + (int)v.y, b.w, b.h}; +} +inline BoundingBox operator+(Vector2 v, BoundingBox b) { + return b + v; +} + +#endif diff --git a/common/utilities/config_utility.cpp b/common/utilities/config_utility.cpp index 02970b1..e34a2db 100644 --- a/common/utilities/config_utility.cpp +++ b/common/utilities/config_utility.cpp @@ -25,25 +25,37 @@ #include #include -using namespace std; +void ConfigUtility::Load(std::string fname) { + //clear the stored configuration + configMap.clear(); + //pass to the recursive method + configMap = Read(fname); +} -void ConfigUtility::Load(string fname) { - ifstream is(fname); +ConfigUtility::table_t ConfigUtility::Read(std::string fname) { + //read in and return this file's data + table_t retTable; + std::ifstream is(fname); if (!is.is_open()) { - throw(runtime_error("Failed to open config file")); + std::string msg; + msg += "Failed to open a config file: "; + msg += fname; + throw(std::runtime_error(msg)); } - string key, val; + std::string key, val; - for (;;) { //forever + while(true) { //forever //eat whitespace - while(isspace(is.peek())) + while(isspace(is.peek())) { is.ignore(); + } //end of file - if (is.eof()) + if (is.eof()) { break; + } //skip comment lines if (is.peek() == '#') { @@ -64,41 +76,54 @@ void ConfigUtility::Load(string fname) { while(key.size() && isspace(*(key.end()-1))) key.erase(key.end() - 1); while(val.size() && isspace(*(val.end()-1))) val.erase(val.end() - 1); - //allow empty/wiped values + //disallow empty/wiped values if (key.size() == 0) { continue; } //save the pair - table[key] = val; + retTable[key] = val; } is.close(); + + //load in any subordinate config files + //TODO: Possibility of nesting config levels? + if (retTable.find("config.next") != retTable.end()) { + table_t subTable = Read(retTable["config.next"]); + retTable.insert(subTable.begin(), subTable.end()); + } + + return retTable; } +//------------------------- +//Convert to a type +//------------------------- + std::string& ConfigUtility::String(std::string s) { - return table[s]; + return configMap[s]; } int ConfigUtility::Integer(std::string s) { - std::map::iterator it = table.find(s); - if (it == table.end()) { + table_t::iterator it = configMap.find(s); + if (it == configMap.end()) { return 0; } return atoi(it->second.c_str()); } double ConfigUtility::Double(std::string s) { - std::map::iterator it = table.find(s); - if (it == table.end()) { + table_t::iterator it = configMap.find(s); + if (it == configMap.end()) { return 0.0; } return atof(it->second.c_str()); } bool ConfigUtility::Boolean(std::string s) { - std::map::iterator it = table.find(s); - if (it == table.end()) { + table_t::iterator it = configMap.find(s); + if (it == configMap.end()) { return false; } return it->second == "true"; diff --git a/common/utilities/config_utility.hpp b/common/utilities/config_utility.hpp index 6e944ef..8b85528 100644 --- a/common/utilities/config_utility.hpp +++ b/common/utilities/config_utility.hpp @@ -22,14 +22,13 @@ #ifndef CONFIGUTILITY_HPP_ #define CONFIGUTILITY_HPP_ +#include "singleton.hpp" + #include #include -class ConfigUtility { +class ConfigUtility : public Singleton { public: - ConfigUtility() = default; - ConfigUtility(std::string s) { Load(s); } - void Load(std::string fname); //convert to a type @@ -39,22 +38,21 @@ public: bool Boolean(std::string); //shorthand - std::string& operator[](std::string s) { - return String(s); - } - int Int(std::string s) { - return Integer(s); - } - bool Bool(std::string s) { - return Boolean(s); - } + inline std::string& operator[](std::string s) { return configMap[s]; } + inline int Int(std::string s) { return Integer(s); } + inline bool Bool(std::string s) { return Boolean(s); } - //OO breaker - std::map* GetMap() { - return &table; - } private: - std::map table; + typedef std::map table_t; + + friend Singleton; + + ConfigUtility() = default; + ~ConfigUtility() = default; + + table_t Read(std::string fname); + + table_t configMap; }; #endif diff --git a/common/utilities/singleton.hpp b/common/utilities/singleton.hpp new file mode 100644 index 0000000..379003a --- /dev/null +++ b/common/utilities/singleton.hpp @@ -0,0 +1,63 @@ +/* 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 SINGLETON_HPP_ +#define SINGLETON_HPP_ + +#include + +template +class Singleton { +public: + static T& GetSingleton() { + if (!ptr) { + throw(std::logic_error("This singleton has not been created")); + } + return *ptr; + } + static void Create() { + if (ptr) { + throw(std::logic_error("This singleton has already been created")); + } + ptr = new T(); + } + static void Delete() { + if (!ptr) { + throw(std::logic_error("A non-existant singleton cannot be deleted")); + } + delete ptr; + ptr = nullptr; + } + +protected: + Singleton() = default; + Singleton(Singleton const&) = default; + Singleton(Singleton&&) = default; + ~Singleton() = default; + +private: + static T* ptr; +}; + +template +T* Singleton::ptr = nullptr; + +#endif \ No newline at end of file diff --git a/common/utilities/utility.cpp b/common/utilities/utility.cpp index a8a7270..bbba99c 100644 --- a/common/utilities/utility.cpp +++ b/common/utilities/utility.cpp @@ -32,6 +32,10 @@ int snapToBase(int base, int x) { return x / base * base; } +double snapToBase(double base, double x) { + return floor(x / base) * base; +} + std::string truncatePath(std::string pathname) { return std::string( std::find_if( diff --git a/common/utilities/utility.hpp b/common/utilities/utility.hpp index 3589c01..3346136 100644 --- a/common/utilities/utility.hpp +++ b/common/utilities/utility.hpp @@ -25,6 +25,8 @@ #include int snapToBase(int base, int x); +double snapToBase(double base, double x); + std::string truncatePath(std::string pathname); //fixing known bugs in g++ diff --git a/common/utilities/vector2.hpp b/common/utilities/vector2.hpp index 2be3d34..57c716c 100644 --- a/common/utilities/vector2.hpp +++ b/common/utilities/vector2.hpp @@ -43,6 +43,8 @@ public: } void Normalize() { double l = Length(); + if (l == 0) + throw(std::domain_error("Divide by zero")); x /= l; y /= l; } diff --git a/makefile b/makefile index 56e39a3..3a5a667 100644 --- a/makefile +++ b/makefile @@ -4,9 +4,9 @@ #RM=del /y #CXXFLAGS+=-static-libgcc -static-libstdc++ -g -fno-inline-functions -Wall -CXXFLAGS+=-static-libgcc -static-libstdc++ +#CXXFLAGS+=-static-libgcc -static-libstdc++ -export +#export OUTDIR=out @@ -15,6 +15,12 @@ all: $(OUTDIR) $(MAKE) -C server $(MAKE) -C client +debug: export CXXFLAGS+=-g +debug: clean all + +release: export CXXFLAGS+=-static-libgcc -static-libstdc++ +release: clean all + $(OUTDIR): mkdir $(OUTDIR) diff --git a/rsc/config.cfg b/rsc/config.cfg index b2f34d9..bbe6611 100644 --- a/rsc/config.cfg +++ b/rsc/config.cfg @@ -8,6 +8,8 @@ server.name = local server.dbname = database.db #client specific settings +#client.screen.w = 800 +#client.screen.h = 600 client.screen.f = false client.username = Kayne Ruse diff --git a/rsc/scripts/setup_server.lua b/rsc/scripts/setup_server.lua index 582cacf..ce07f88 100644 --- a/rsc/scripts/setup_server.lua +++ b/rsc/scripts/setup_server.lua @@ -1,38 +1,39 @@ print("Lua script check") --uber lazy declarations -function square(x) return x*x end -function distance(x, y, i, j) return math.sqrt(square(x - i) + square(y - j)) end +function math.sqr(x) return x*x end +function math.dist(x, y, i, j) return math.sqrt(math.sqr(x - i) + math.sqr(y - j)) end --tile macros, mapped to the tilesheet local base = 14 local shift = 36 -plains = base + shift * 0 -grass = base + shift * 1 -dirt = base + shift * 2 -sand = base + shift * 3 -water = base + shift * 4 +tiles = { + plains = base + shift * 0, + grass = base + shift * 1, + dirt = base + shift * 2, + sand = base + shift * 3, + water = base + shift * 4 +} ---Overwrite the original OnCreate with my own version -Region.hcOnCreate = Region.OnCreate -Region.OnCreate = function(region) - local ret = Region.hcOnCreate(region) --best practices +--could set custom generation systems here, that differ from the global generators, etc. +function Region.Create(region) for i = 1, Region.GetWidth() do for j = 1, Region.GetHeight() do - local dist = distance(0, 0, i + Region.GetX(region) -1, j + Region.GetY(region) -1) + local dist = math.dist(0, 0, i + Region.GetX(region) -1, j + Region.GetY(region) -1) if dist < 10 then - Region.SetTile(region, i, j, 1, plains) + Region.SetTile(region, i, j, 1, tiles.plains) elseif dist < 12 then - Region.SetTile(region, i, j, 1, sand) + Region.SetTile(region, i, j, 1, tiles.sand) else - Region.SetTile(region, i, j, 1, water) + Region.SetTile(region, i, j, 1, tiles.water) + Region.SetSolid(region, i, j, true) end end end - return ret end --Get some regions +--BUG: The server fails without this newRoom = RoomMgr.CreateRoom("overworld") pager = Room.GetPager(newRoom) regionTable = { @@ -42,4 +43,4 @@ regionTable = { RegionPager.GetRegion(pager, Region.GetWidth() *-1, Region.GetHeight() *-1) } -print("Finished the lua script") \ No newline at end of file +print("Finished the lua script") diff --git a/server/linit.cpp b/server/linit.cpp index 1d79c96..072120f 100644 --- a/server/linit.cpp +++ b/server/linit.cpp @@ -38,6 +38,7 @@ #include "region_api.hpp" #include "region_pager_api.hpp" +#include "tile_sheet_api.hpp" #include "room_api.hpp" #include "room_mgr_api.hpp" @@ -58,6 +59,7 @@ static const luaL_Reg loadedlibs[] = { //Tortuga's API {TORTUGA_REGION_NAME, openRegionAPI}, {TORTUGA_REGION_PAGER_NAME, openRegionPagerAPI}, + {TORTUGA_TILE_SHEET_NAME, openTileSheetAPI}, {TORTUGA_ROOM_NAME, openRoomAPI}, {TORTUGA_ROOM_MGR_NAME, openRoomMgrAPI}, diff --git a/server/main.cpp b/server/main.cpp index 5c01971..4fbc24a 100644 --- a/server/main.cpp +++ b/server/main.cpp @@ -21,6 +21,9 @@ */ #include "server_application.hpp" +//singletons +#include "config_utility.hpp" + #include #include @@ -28,10 +31,19 @@ using namespace std; int main(int argc, char** argv) { try { - ServerApplication app; + //create the singletons + ConfigUtility::Create(); + ServerApplication::Create(); + + //call the server's routines + ServerApplication& app = ServerApplication::GetSingleton(); app.Init(argc, argv); app.Proc(); app.Quit(); + + //delete the singletons + ConfigUtility::Delete(); + ServerApplication::Delete(); } catch(exception& e) { cerr << "Fatal exception thrown: " << e.what() << endl; diff --git a/server/makefile b/server/makefile index 3d0de76..807cd13 100644 --- a/server/makefile +++ b/server/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. accounts characters combat enemies mapgen mapgen/generators rooms ../common/gameplay ../common/map ../common/network ../common/network/packet ../common/network/serial ../common/utilities +INCLUDES+=. accounts characters combat enemies mapgen mapgen/generators rooms ../common/debugging ../common/gameplay ../common/map ../common/network ../common/network/packet ../common/network/serial ../common/utilities LIBS+=server.a ../libcommon.a -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL -llua -lsqlite3 CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) diff --git a/server/server_application.hpp b/server/server_application.hpp index c5d0c1d..6c99d2d 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -31,6 +31,7 @@ //common utilities #include "udp_network_utility.hpp" #include "config_utility.hpp" +#include "singleton.hpp" //APIs #include "lua/lua.hpp" @@ -42,17 +43,19 @@ #include //The main application class -class ServerApplication { +class ServerApplication: public Singleton { public: //public methods - ServerApplication() = default; - ~ServerApplication() = default; - void Init(int argc, char** argv); void Proc(); void Quit(); private: + friend Singleton; + + ServerApplication() = default; + ~ServerApplication() = default; + //handle incoming traffic void HandlePacket(SerialPacket* const); @@ -83,7 +86,7 @@ private: sqlite3* database = nullptr; lua_State* luaState = nullptr; UDPNetworkUtility network; - ConfigUtility config; + ConfigUtility& config = ConfigUtility::GetSingleton(); //simple tables std::map clientMap;