From 0b6a988184e6852864190f2cee4b756668c75f5f Mon Sep 17 00:00:00 2001 From: Tiberiu Chibici Date: Thu, 1 Dec 2016 21:08:28 +0200 Subject: [PATCH] Large refactoring. Also, reimplemented resource manager to use parsers. Changed from json to xml (it allows comments!!!). --- assets/config/Default.config | 4 + assets/items/lvl1_sword.item | 15 ++ assets/items/stone_pickaxe.item | 16 ++ assets/levels/Farm.back | 8 + assets/levels/Farm.level | 17 -- assets/scenes/Game.scene | 29 ++++ assets/sprites/Player.sprite | 41 +++++ assets/sprites/items/lvl1_sword.sprite | 36 ++++ assets/sprites/items/stone_pickaxe.sprite | 36 ++++ assets/sprites/player.sprite | 148 ---------------- assets/ui/mini_inventory.png | Bin 0 -> 237 bytes assets_original/inventory_active.xcf | Bin 0 -> 1183 bytes build/prepareAssets.py | 9 +- src/GameState.cpp | 14 ++ src/GameState.h | 23 +-- src/Main.cpp | 5 + src/base/Camera.cpp | 35 ++++ src/base/Camera.h | 10 +- src/base/GameObject.h | 3 + src/base/Scene.h | 25 +++ src/base/Sprite.cpp | 35 ++-- src/base/Sprite.h | 9 +- src/controller/FarmlandsGame.cpp | 82 ++------- src/controller/FarmlandsGame.h | 3 - src/controller/items/ItemController.cpp | 30 ++++ src/controller/items/ItemController.h | 30 ++++ .../{ => player}/PlayerController.cpp | 71 ++++---- .../{ => player}/PlayerController.h | 11 +- src/graphics/BackgroundRenderer.cpp | 19 +- src/graphics/BackgroundRenderer.h | 7 +- src/graphics/SpriteRenderer.cpp | 6 +- src/gui/widgets/TextArea.cpp | 2 +- src/input/GameKey.h | 23 ++- src/input/GameKeyConfiguration.cpp | 23 ++- src/model/Background.cpp | 61 +++++++ src/model/{Level.h => Background.h} | 31 ++-- src/model/Configuration.h | 25 +-- src/model/Level.cpp | 62 ------- src/model/Player.h | 36 ---- src/resources/ResourceInfo.h | 9 +- src/resources/ResourceManager.cpp | 162 ++++++++++++++++++ src/resources/ResourceManager.h | 37 ++-- .../ResourceManager/ResourceManager.cpp | 102 ----------- .../ResourceManager/ResourceManager_Fonts.cpp | 37 ---- .../ResourceManager_Levels.cpp | 114 ------------ .../ResourceManager_Sprites.cpp | 92 ---------- .../ResourceManager_Textures.cpp | 55 ------ src/resources/Resources.g.h | 52 ++++-- src/storage/Parse.cpp | 10 ++ src/storage/Parse.h | 87 ++++++++++ src/storage/Parsers.h | 22 +++ src/storage/parsers/ParseComponents_base.cpp | 39 +++++ src/storage/parsers/ParseComponents_base.h | 27 +++ .../parsers/ParseComponents_controller.cpp | 36 ++++ .../parsers/ParseComponents_controller.h | 27 +++ .../parsers/ParseComponents_graphics.cpp | 42 +++++ .../parsers/ParseComponents_graphics.h | 27 +++ src/storage/parsers/ParseComponents_model.cpp | 92 ++++++++++ src/storage/parsers/ParseComponents_model.h | 27 +++ src/storage/parsers/ParseConfiguration.cpp | 30 ++++ src/storage/parsers/ParseConfiguration.h | 23 +++ src/storage/parsers/ParseGameObject.cpp | 61 +++++++ src/storage/parsers/ParseGameObject.h | 30 ++++ src/storage/parsers/ParseScene.cpp | 39 +++++ src/storage/parsers/ParseScene.h | 27 +++ src/storage/parsers/ParseSprite.cpp | 84 +++++++++ src/storage/parsers/ParseSprite.h | 29 ++++ src/utils/DumpPropertyTree.cpp | 43 +++++ src/utils/DumpPropertyTree.h | 21 +++ src/utils/Exceptions.cpp | 4 +- src/utils/Exceptions.h | 4 +- 71 files changed, 1608 insertions(+), 923 deletions(-) create mode 100644 assets/config/Default.config create mode 100644 assets/items/lvl1_sword.item create mode 100644 assets/items/stone_pickaxe.item create mode 100644 assets/levels/Farm.back delete mode 100644 assets/levels/Farm.level create mode 100644 assets/scenes/Game.scene create mode 100644 assets/sprites/Player.sprite create mode 100644 assets/sprites/items/lvl1_sword.sprite create mode 100644 assets/sprites/items/stone_pickaxe.sprite delete mode 100644 assets/sprites/player.sprite create mode 100644 assets/ui/mini_inventory.png create mode 100644 assets_original/inventory_active.xcf create mode 100644 src/base/Camera.cpp create mode 100644 src/base/Scene.h create mode 100644 src/controller/items/ItemController.cpp create mode 100644 src/controller/items/ItemController.h rename src/controller/{ => player}/PlayerController.cpp (72%) rename src/controller/{ => player}/PlayerController.h (91%) create mode 100644 src/model/Background.cpp rename src/model/{Level.h => Background.h} (52%) delete mode 100644 src/model/Level.cpp delete mode 100644 src/model/Player.h create mode 100644 src/resources/ResourceManager.cpp delete mode 100644 src/resources/ResourceManager/ResourceManager.cpp delete mode 100644 src/resources/ResourceManager/ResourceManager_Fonts.cpp delete mode 100644 src/resources/ResourceManager/ResourceManager_Levels.cpp delete mode 100644 src/resources/ResourceManager/ResourceManager_Sprites.cpp delete mode 100644 src/resources/ResourceManager/ResourceManager_Textures.cpp create mode 100644 src/storage/Parse.cpp create mode 100644 src/storage/Parse.h create mode 100644 src/storage/Parsers.h create mode 100644 src/storage/parsers/ParseComponents_base.cpp create mode 100644 src/storage/parsers/ParseComponents_base.h create mode 100644 src/storage/parsers/ParseComponents_controller.cpp create mode 100644 src/storage/parsers/ParseComponents_controller.h create mode 100644 src/storage/parsers/ParseComponents_graphics.cpp create mode 100644 src/storage/parsers/ParseComponents_graphics.h create mode 100644 src/storage/parsers/ParseComponents_model.cpp create mode 100644 src/storage/parsers/ParseComponents_model.h create mode 100644 src/storage/parsers/ParseConfiguration.cpp create mode 100644 src/storage/parsers/ParseConfiguration.h create mode 100644 src/storage/parsers/ParseGameObject.cpp create mode 100644 src/storage/parsers/ParseGameObject.h create mode 100644 src/storage/parsers/ParseScene.cpp create mode 100644 src/storage/parsers/ParseScene.h create mode 100644 src/storage/parsers/ParseSprite.cpp create mode 100644 src/storage/parsers/ParseSprite.h create mode 100644 src/utils/DumpPropertyTree.cpp create mode 100644 src/utils/DumpPropertyTree.h diff --git a/assets/config/Default.config b/assets/config/Default.config new file mode 100644 index 0000000..c912747 --- /dev/null +++ b/assets/config/Default.config @@ -0,0 +1,4 @@ + + + 60 + \ No newline at end of file diff --git a/assets/items/lvl1_sword.item b/assets/items/lvl1_sword.item new file mode 100644 index 0000000..9541784 --- /dev/null +++ b/assets/items/lvl1_sword.item @@ -0,0 +1,15 @@ +{ + "name" : "Level 1 Sword", + "description" : "Most basic sword.", + "enemyDamage" : 3, + "attackDuration" : 10, + "criticalProbability" : 0.01, + + "level" : 1, + + "tool" : true, + "giftable" : false, + "sellable" : false, + + "sprite" : "sprites/items/lvl1_sword.sprite" +} \ No newline at end of file diff --git a/assets/items/stone_pickaxe.item b/assets/items/stone_pickaxe.item new file mode 100644 index 0000000..7de64ec --- /dev/null +++ b/assets/items/stone_pickaxe.item @@ -0,0 +1,16 @@ +{ + "name" : "Stone pickaxe", + "description" : "The most basic type of pickaxe. It can break small stones.", + "enemyDamage" : 1, + "criticalProbability" : 0, + + "level" : 1, + + "tool" : true, + "giftable" : false, + "sellable" : false, + + "sprite" : "sprites/items/stone_pickaxe.sprite", + + "controller" : "PickaxeItem" +} \ No newline at end of file diff --git a/assets/levels/Farm.back b/assets/levels/Farm.back new file mode 100644 index 0000000..4e1cce0 --- /dev/null +++ b/assets/levels/Farm.back @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/assets/levels/Farm.level b/assets/levels/Farm.level deleted file mode 100644 index 2c16e27..0000000 --- a/assets/levels/Farm.level +++ /dev/null @@ -1,17 +0,0 @@ -{ - "cellWidth": 16, - "cellHeight": 16, - - "layerCount" : 1, - "width" : 380, - "height" : 213, - - "layers": - [ - { - "name" : "Background", - "cellsFile" : "levels/Farm_Background.csv", - "textureFile" : "tilesets/Ground.png" - } - ] -} \ No newline at end of file diff --git a/assets/scenes/Game.scene b/assets/scenes/Game.scene new file mode 100644 index 0000000..50302fc --- /dev/null +++ b/assets/scenes/Game.scene @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/sprites/Player.sprite b/assets/sprites/Player.sprite new file mode 100644 index 0000000..b73bd84 --- /dev/null +++ b/assets/sprites/Player.sprite @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/sprites/items/lvl1_sword.sprite b/assets/sprites/items/lvl1_sword.sprite new file mode 100644 index 0000000..719bf11 --- /dev/null +++ b/assets/sprites/items/lvl1_sword.sprite @@ -0,0 +1,36 @@ +{ + "name" : "Level 1 sword", + "anchorX" : 0, + "anchorY" : 1, + + "states" : + [ + { + "name" : "Normal", + "frames" : + [ + { + "tileSet" : "tilesets/PlayerTiles.png", + "cell" : 0, + "width" : 1, + "height" : 2, + "duration" : 1 + } + ] + }, + + { + "name" : " Attack", + "frames" : + [ + { + "tileSet" : "tilesets/PlayerTiles.png", + "cell" : 2, + "width" : 1, + "height" : 2, + "duration" : 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/assets/sprites/items/stone_pickaxe.sprite b/assets/sprites/items/stone_pickaxe.sprite new file mode 100644 index 0000000..63ac5c4 --- /dev/null +++ b/assets/sprites/items/stone_pickaxe.sprite @@ -0,0 +1,36 @@ +{ + "name" : "Stone pickaxe", + "anchorX" : 0, + "anchorY" : 1, + + "states" : + [ + { + "name" : "Normal", + "frames" : + [ + { + "tileSet" : "tilesets/PlayerTiles.png", + "cell" : 0, + "width" : 1, + "height" : 2, + "duration" : 1 + } + ] + }, + + { + "name" : "Attack", + "frames" : + [ + { + "tileSet" : "tilesets/PlayerTiles.png", + "cell" : 2, + "width" : 1, + "height" : 2, + "duration" : 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/assets/sprites/player.sprite b/assets/sprites/player.sprite deleted file mode 100644 index fa65df7..0000000 --- a/assets/sprites/player.sprite +++ /dev/null @@ -1,148 +0,0 @@ -{ - "name" : "Player", - "anchorX" : 0.5, - "anchorY" : 1, - - "states" : - [ - { - "name" : "Idle right", - "frames" : - [ - { - "tileSet" : "tilesets/PlayerTiles.png", - "cell" : 0, - "width" : 1, - "height" : 2, - "duration" : 1 - } - ] - }, - - { - "name" : "Idle up", - "frames" : - [ - { - "tileSet" : "tilesets/PlayerTiles.png", - "cell" : 2, - "width" : 1, - "height" : 2, - "duration" : 1 - } - ] - }, - - { - "name" : "Idle left", - "frames" : - [ - { - "tileSet" : "tilesets/PlayerTiles.png", - "cell" : 4, - "width" : 1, - "height" : 2, - "duration" : 1 - } - ] - }, - - { - "name" : "Idle down", - "frames" : - [ - { - "tileSet" : "tilesets/PlayerTiles.png", - "cell" : 6, - "width" : 1, - "height" : 2, - "duration" : 1 - } - ] - }, - - { - "name" : "Walking right", - "frames" : - [ - { - "tileSet" : "tilesets/PlayerTiles.png", - "cell" : 0, - "width" : 1, - "height" : 2, - "duration" : 7 - }, - { - "tileSet" : "tilesets/PlayerTiles.png", - "cell" : 1, - "width" : 1, - "height" : 2, - "duration" : 7 - } - ] - }, - - { - "name" : "Walking up", - "frames" : - [ - { - "tileSet" : "tilesets/PlayerTiles.png", - "cell" : 2, - "width" : 1, - "height" : 2, - "duration" : 7 - }, - { - "tileSet" : "tilesets/PlayerTiles.png", - "cell" : 3, - "width" : 1, - "height" : 2, - "duration" : 7 - } - ] - }, - - { - "name" : "Walking left", - "frames" : - [ - { - "tileSet" : "tilesets/PlayerTiles.png", - "cell" : 4, - "width" : 1, - "height" : 2, - "duration" : 7 - }, - { - "tileSet" : "tilesets/PlayerTiles.png", - "cell" : 5, - "width" : 1, - "height" : 2, - "duration" : 7 - } - ] - }, - - { - "name" : "Walking down", - "frames" : - [ - { - "tileSet" : "tilesets/PlayerTiles.png", - "cell" : 6, - "width" : 1, - "height" : 2, - "duration" : 7 - }, - { - "tileSet" : "tilesets/PlayerTiles.png", - "cell" : 7, - "width" : 1, - "height" : 2, - "duration" : 7 - } - ] - } - ] -} \ No newline at end of file diff --git a/assets/ui/mini_inventory.png b/assets/ui/mini_inventory.png new file mode 100644 index 0000000000000000000000000000000000000000..3b1b0d592b580f5f527de10ea1095c20d9d1726b GIT binary patch literal 237 zcmeAS@N?(olHy`uVBq!ia0vp^3P3Et!3HGD8EPYe6kC$Fy9>jA5L~c#`DCC7XMsm# zF#`j)FbFd;%$g$s6l5>)^mS!_z%3`LWYU;hJP{})S>hT|;+&tGo0?a`;9QiNSdyBe zP@Y+mq2TW68xY>eCk|8;>gnPb;&D9rj^X-8_ROpfe-0XZZ86?p00bSyb;{nK4{!gk zz~jrf>C67R)iWDA6B`b$V0M!=c-0Wd-eZ+;g;B?TUu|N=kKP*Qdv?`l4t#iHc=H$I Y=SY!x6EDfA04-qfboFyt=akR{0A9UJ=l}o! literal 0 HcmV?d00001 diff --git a/assets_original/inventory_active.xcf b/assets_original/inventory_active.xcf new file mode 100644 index 0000000000000000000000000000000000000000..b5e339ad9127e827cd93cd3541e6e31d2984295f GIT binary patch literal 1183 zcmd6l%}&BV5XVbZL$P;{yWp%bgOf-M}0-38aJ2#K|xgnh$B!g2k98J2davYPC$kG zZ$UsooPu^i*l?aO4xPd9Bh<1Edq|3Hn#}TGEyQnpaG2~dm40xqOP`)!-|$H_Zsn$| zGf8*2ns!Gu*9#0rUEAPly;#$9#Wrk**5V>LdPk;>%SIdk&FkjP?H#>JofPUY+SxFg zK3|_$IymaPJz3$F{%;m*!3Hm}q<4#Zlv_%dxj1cWn#;W9Il&6nt%b8XieDj#+;2)y zDG09$zi0kM4wwTV;1yxyL3k~5P$6OLJV+RdaFO9+h7U7b%5XWu1Q_3&#y$Y h9I1oKfT+YL?Z~%E*34*QZf!3|Eu&(P)~6`U{{Ve`gGK-V literal 0 HcmV?d00001 diff --git a/build/prepareAssets.py b/build/prepareAssets.py index 505d704..365c91c 100755 --- a/build/prepareAssets.py +++ b/build/prepareAssets.py @@ -45,10 +45,13 @@ RINFO_FOOTER=" };\n" # FILE_TYPES = [ ([".png", ".bmp"], "Texture"), - ([".level"], "Level"), - ([".csv"], "LevelLayer"), ([".ttf"], "Font"), - ([".sprite"], "Sprite"), + ([".sprite"], "Sprite"), + ([".config"], "Configuration"), + ([".scene"], "Scene"), + ([".back"], "Background"), + ([".csv"], "BackgroundLayer"), + ([".item"], "Item"), ] diff --git a/src/GameState.cpp b/src/GameState.cpp index b8493a9..b130e05 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -10,6 +10,20 @@ namespace farmlands { GameState GameState::s_current; +GameState::GameState() + : renderContext(), + scene(nullptr), + config(nullptr), + elapsedTime(0) +{ +} + +GameState::~GameState() +{ + if (scene) delete scene; + if (config) delete config; +} + GameState& farmlands::GameState::current() { return s_current; diff --git a/src/GameState.h b/src/GameState.h index b345bfc..b5d2f15 100644 --- a/src/GameState.h +++ b/src/GameState.h @@ -10,8 +10,7 @@ #include #include -#include -#include +#include #include #include @@ -19,30 +18,20 @@ namespace farmlands { - struct GuiState - { - }; - class GameState { public: + GameState(); + ~GameState(); static GameState& current(); static void setCurrent(GameState& state); // Render context base::RenderContext renderContext; + base::Scene* scene; + model::Configuration* config; - // Gui - GuiState gui; - - // Settings - model::Configuration config; - - // Current game - model::Player player; - model::Level* currentLevel; - base::GameObject root; - + // Misc float elapsedTime; private: diff --git a/src/Main.cpp b/src/Main.cpp index 087f8ef..c318219 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -17,4 +17,9 @@ int main() std::cerr << typeid(ex).name() << " : " << ex.message() << "\n"; std::cerr << "Source: file " << ex.file() << " line " << ex.line() << "\n"; } + catch (std::exception& ex) + { + std::cerr << "Panic: Caught unhandled exception!\n"; + std::cerr << typeid(ex).name() << " : " << ex.what() << "\n"; + } } diff --git a/src/base/Camera.cpp b/src/base/Camera.cpp new file mode 100644 index 0000000..5409f88 --- /dev/null +++ b/src/base/Camera.cpp @@ -0,0 +1,35 @@ +/* + * Camera.cpp + * + * Created on: Dec 1, 2016 + * Author: tibi + */ + +#include +#include +#include + +namespace farmlands { +namespace base { + +Camera::Camera() + : scale(1), + mainCamera(true) +{ +} + +Camera::~Camera() +{ +} + +void Camera::onCreate() +{ + if (mainCamera) + { + GameState::current().renderContext.setCamera(gameObject); + } +} + +} +} + diff --git a/src/base/Camera.h b/src/base/Camera.h index d612780..5a0fc7b 100644 --- a/src/base/Camera.h +++ b/src/base/Camera.h @@ -13,9 +13,17 @@ namespace farmlands { namespace base { - struct Camera : public Component + class Camera : public Component { + public: + Camera(); + virtual ~Camera(); + + virtual void onCreate(); + float scale; + bool mainCamera; + }; } diff --git a/src/base/GameObject.h b/src/base/GameObject.h index ef5de83..df79949 100644 --- a/src/base/GameObject.h +++ b/src/base/GameObject.h @@ -52,6 +52,9 @@ namespace base { void onPostRender(); void onDestroy(); + // Other properties + std::string name; + private: std::unordered_map m_components; diff --git a/src/base/Scene.h b/src/base/Scene.h new file mode 100644 index 0000000..05bfaf4 --- /dev/null +++ b/src/base/Scene.h @@ -0,0 +1,25 @@ +/* + * Scene.h + * + * Created on: Dec 1, 2016 + * Author: tibi + */ + +#ifndef MODEL_SCENE_H_ +#define MODEL_SCENE_H_ + +#include + +namespace farmlands { +namespace base { + + struct Scene + { + GameObject root; + uint32_t cellWidth, cellHeight; + }; + +} /* namespace model */ +} /* namespace farmlands */ + +#endif /* MODEL_SCENE_H_ */ diff --git a/src/base/Sprite.cpp b/src/base/Sprite.cpp index 0e7d3c1..bef3819 100644 --- a/src/base/Sprite.cpp +++ b/src/base/Sprite.cpp @@ -19,7 +19,8 @@ Sprite::Sprite() m_states(), m_currentState(0), m_currentFrame(0), - m_currentFrameTimeLeft(0) + m_currentFrameTimeLeft(0), + m_animationVelocity(1) { } @@ -53,7 +54,7 @@ void Sprite::setState(size_t stateId) m_currentState = stateId; m_currentFrame = 0; - m_currentFrameTimeLeft = currentFrame().duration * 1; + m_currentFrameTimeLeft = currentFrame().duration; } void Sprite::setState(const std::string& name) @@ -62,28 +63,19 @@ void Sprite::setState(const std::string& name) setState(m_stateNames.at(name)); } -void Sprite::advanceTime(uint32_t steps) +void Sprite::advanceTime(float fractions) { Assert(m_states.size() > 0, "Sprite must have at least one state!"); - while (steps > 0) + m_currentFrameTimeLeft -= fractions * m_animationVelocity; + + while (m_currentFrameTimeLeft <= 0) { - // There is time left in the current frame? - if (m_currentFrameTimeLeft > 0) - { - uint32_t sub = std::min(steps, m_currentFrameTimeLeft); - m_currentFrameTimeLeft -= sub; - steps -= sub; - } + // Move to the next frame + if (++m_currentFrame >= currentState().frames.size()) + m_currentFrame = 0; - if (m_currentFrameTimeLeft == 0) - { - // Move to the next frame - if (++m_currentFrame >= currentState().frames.size()) - m_currentFrame = 0; - - m_currentFrameTimeLeft = currentFrame().duration * 1; - } + m_currentFrameTimeLeft += currentFrame().duration; } } @@ -93,6 +85,11 @@ SpriteState& Sprite::currentState() return m_states.at(m_currentState); } +void Sprite::setAnimationVelocity(float velocity) +{ + m_animationVelocity = velocity; +} + Frame& Sprite::currentFrame() { Assert(currentState().frames.size() > 0, "State must have at least one frame!"); diff --git a/src/base/Sprite.h b/src/base/Sprite.h index f166032..494fc44 100644 --- a/src/base/Sprite.h +++ b/src/base/Sprite.h @@ -63,8 +63,12 @@ namespace base { /** * Advances the current frame */ - void advanceTime(uint32_t steps); + void advanceTime(float fractions); + /** + * Sets the animation velocity. Using this property, animation can be slowed or accelerated. + */ + void setAnimationVelocity(float velocity); // Getters SpriteState& currentState(); @@ -80,7 +84,8 @@ namespace base { size_t m_currentState; size_t m_currentFrame; - uint32_t m_currentFrameTimeLeft; + float m_currentFrameTimeLeft; + float m_animationVelocity; }; } /* namespace model */ diff --git a/src/controller/FarmlandsGame.cpp b/src/controller/FarmlandsGame.cpp index dcfd32c..bd55262 100644 --- a/src/controller/FarmlandsGame.cpp +++ b/src/controller/FarmlandsGame.cpp @@ -34,63 +34,6 @@ FarmlandsGame::FarmlandsGame() : { } -void FarmlandsGame::createScene() -{ - // Create camera - Transform* cameraTransform = new Transform(); - cameraTransform->x = 120; - cameraTransform->y = 100 - 1; - - Camera* camera = new Camera(); - camera->scale = 4.0f; - - GameObject* cameraObj = new GameObject(); - cameraObj->addComponent(cameraTransform); - cameraObj->addComponent(camera); - - GameState::current().root.addChild(cameraObj); - GameState::current().renderContext.setCamera(cameraObj); - cameraObj->onCreate(); - - // Create background - BackgroundRenderer* backRenderer = new BackgroundRenderer(); - backRenderer->level = GameState::current().currentLevel; - - GameObject* backObj = new GameObject(); - backObj->addComponent(backRenderer); - - GameState::current().root.addChild(backObj); - backObj->onCreate(); - - // Create player - Transform* playerTransform = new Transform(); - playerTransform->x = 120; - playerTransform->y = 100; - - SpriteRenderer* playerRender = new SpriteRenderer(); - playerRender->sprite = ResourceManager::instance().sprite(R::Sprites::Player); - - PlayerController* playerCtrl = new PlayerController(); - - GameObject* playerObj = new GameObject(); - playerObj->addComponent(playerTransform); - playerObj->addComponent(playerRender); - playerObj->addComponent(playerCtrl); - - GameState::current().root.addChild(playerObj); - playerObj->onCreate(); - - // Create debug object - DebugController* dbgController = new DebugController(); - - GameObject* dbgObj = new GameObject(); - dbgObj->addComponent(dbgController); - - GameState::current().root.addChild(dbgObj); - dbgObj->onCreate(); - -} - bool FarmlandsGame::initialize() { bool ok = true; @@ -102,41 +45,36 @@ bool FarmlandsGame::initialize() // Initialize & load resources ResourceManager::instance().initialize(); - ResourceManager::instance().loadGameAssets(); - ResourceManager::instance().loadLevel(resources::R::Levels::Farm); - GameState::current().currentLevel = ResourceManager::instance().level(resources::R::Levels::Farm); - GameState::current().renderContext.viewport.pixelsPerUnitX = GameState::current().currentLevel->m_cellWidth; - GameState::current().renderContext.viewport.pixelsPerUnitY = GameState::current().currentLevel->m_cellHeight; - - // Set up scene - createScene(); + ResourceManager::instance().loadGame(); + GameState::current().renderContext.viewport.pixelsPerUnitX = GameState::current().scene->cellWidth; + GameState::current().renderContext.viewport.pixelsPerUnitY = GameState::current().scene->cellHeight; // Finish initialization - GameState::current().root.onInitialize(); + GameState::current().scene->root.onInitialize(); return true; } void FarmlandsGame::onUpdateLogic() { - GameState::current().root.onUpdateLogic(); + GameState::current().scene->root.onUpdateLogic(); } void FarmlandsGame::onPreRender() { - GameState::current().root.onPreRender(); + GameState::current().scene->root.onPreRender(); SdlRenderer::instance().renderBegin(); } void FarmlandsGame::onRender() { - GameState::current().root.onRender(); + GameState::current().scene->root.onRender(); } void FarmlandsGame::onEvent(SDL_Event& event) { // Let controllers handle event - if (GameState::current().root.onEvent(event)) + if (GameState::current().scene->root.onEvent(event)) return; // Nobody? Handle global events @@ -159,13 +97,13 @@ void FarmlandsGame::onEvent(SDL_Event& event) void FarmlandsGame::onPostRender() { SdlRenderer::instance().renderEnd(); - GameState::current().root.onPostRender(); + GameState::current().scene->root.onPostRender(); } void FarmlandsGame::stop() { m_running = false; - GameState::current().root.onDestroy(); + GameState::current().scene->root.onDestroy(); } int FarmlandsGame::run() diff --git a/src/controller/FarmlandsGame.h b/src/controller/FarmlandsGame.h index b360700..30887af 100644 --- a/src/controller/FarmlandsGame.h +++ b/src/controller/FarmlandsGame.h @@ -9,8 +9,6 @@ #define FARMLANDSGAME_H_ #include -#include -#include #include #include @@ -36,7 +34,6 @@ namespace controller { void stop(); private: - void createScene(); bool m_running; Uint32 m_time; diff --git a/src/controller/items/ItemController.cpp b/src/controller/items/ItemController.cpp new file mode 100644 index 0000000..ff5e602 --- /dev/null +++ b/src/controller/items/ItemController.cpp @@ -0,0 +1,30 @@ +/* + * ItemController.cpp + * + * Created on: Nov 30, 2016 + * Author: tibi + */ + +#include + +namespace farmlands +{ +namespace controller +{ +namespace items +{ + +ItemController::ItemController() +{ + // TODO Auto-generated constructor stub + +} + +ItemController::~ItemController() +{ + // TODO Auto-generated destructor stub +} + +} /* namespace items */ +} /* namespace controller */ +} /* namespace farmlands */ diff --git a/src/controller/items/ItemController.h b/src/controller/items/ItemController.h new file mode 100644 index 0000000..5ebb7e3 --- /dev/null +++ b/src/controller/items/ItemController.h @@ -0,0 +1,30 @@ +/* + * ItemController.h + * + * Created on: Nov 30, 2016 + * Author: tibi + */ + +#ifndef CONTROLLER_ITEMS_ITEMCONTROLLER_H_ +#define CONTROLLER_ITEMS_ITEMCONTROLLER_H_ + +#include + +namespace farmlands { +namespace controller { +namespace items { + + class ItemController: public base::Component + { + public: + ItemController(); + virtual ~ItemController(); + + float enemyDamage; + }; + +} /* namespace items */ +} /* namespace controller */ +} /* namespace farmlands */ + +#endif /* CONTROLLER_ITEMS_ITEMCONTROLLER_H_ */ diff --git a/src/controller/PlayerController.cpp b/src/controller/player/PlayerController.cpp similarity index 72% rename from src/controller/PlayerController.cpp rename to src/controller/player/PlayerController.cpp index ee7172e..e052641 100644 --- a/src/controller/PlayerController.cpp +++ b/src/controller/player/PlayerController.cpp @@ -6,7 +6,7 @@ */ #include -#include +#include #include #include #include @@ -17,21 +17,11 @@ using namespace farmlands::model; namespace farmlands { namespace controller { +namespace player { -/** - * The default velocity of the player when walking (units/sec). - */ -static const float PlayerWalkVelocity = 2.0f; - -/** - * The default velocity of the player when running (units/sec). - */ -static const float PlayerRunVelocity = 4.0f; - -/* - * Movement speed when attacking. - */ -static const float PlayerAttackVelocity = 0.1f; +static const float PlayerWalkVelocity = 2.0f; // The default velocity of the player when walking (units/sec). +static const float PlayerRunVelocity = 4.0f; // The default velocity of the player when running (units/sec). +static const float PlayerAttackVelocity = 0.1f; // Movement speed when attacking. /** * Direction enum based on sign of velocity on x and y @@ -43,12 +33,12 @@ static const Direction VelocitySignDirections[3][3] = { Direction::NorthEast, Direction::East, Direction::SouthEast }, }; - PlayerController::PlayerController() : m_transform(nullptr), m_attackTimeLeft(0), - m_vx(0), m_vy(0), - m_facingDirection(Direction::South) + m_facingDirection(Direction::South), + m_walking(false), + m_running(false) { } @@ -77,18 +67,25 @@ bool PlayerController::onEvent(SDL_Event& event) void PlayerController::onUpdateLogic() { + m_running = false; + m_walking = false; + // Compute movement velocity float velMultiplier = PlayerWalkVelocity; - if (Input::instance().pressed(GameKey::Run)) - velMultiplier = PlayerRunVelocity; - if (m_attackTimeLeft) { velMultiplier = PlayerAttackVelocity; --m_attackTimeLeft; } + else if (Input::instance().pressed(GameKey::Run)) + { + velMultiplier = PlayerRunVelocity; + m_running = true; + } + + // Make movement time independent velMultiplier *= GameState::current().elapsedTime; @@ -97,25 +94,15 @@ void PlayerController::onUpdateLogic() float vy = Input::instance().getY() * velMultiplier; // Check if we can move to the new position - float newX = m_transform->x + m_vx; - float newY = m_transform->y + m_vy; + float newX = m_transform->x + vx; + float newY = m_transform->y + vy; if ((vx || vy) && canMove(newX, newY)) { - m_vx = vx; - m_vy = vy; + m_walking = true; m_transform->x = newX; m_transform->y = newY; m_facingDirection = getDirection(vx, vy); - - base::Transform* cam = GameState::current().renderContext.cameraTransform(); - cam->x = newX; - cam->y = newY - 1; - } - else - { - m_vx = 0; - m_vy = 0; } } @@ -125,8 +112,7 @@ void PlayerController::onPreRender() SpriteRenderer* spriteRenderer = gameObject->component(); // Compute current state - bool idle = (m_vx == 0 && m_vy == 0); - std::string stateName = (idle) ? "Idle " : "Walking "; + std::string stateName = (m_walking) ? "Walking " : "Idle "; if (m_facingDirection & Direction::East) stateName += "right"; @@ -138,6 +124,18 @@ void PlayerController::onPreRender() stateName += "down"; spriteRenderer->sprite->setState(stateName); + + // Set animation velocity + float animVelocity = (m_running) ? 1.0f : 0.7f; + if (m_attackTimeLeft) + animVelocity = 0.1f; + + spriteRenderer->sprite->setAnimationVelocity(animVelocity); + + // Set camera + base::Transform* cam = GameState::current().renderContext.cameraTransform(); + cam->x = m_transform->x; + cam->y = m_transform->y - 1; } bool PlayerController::canMove(float x, float y) @@ -159,5 +157,6 @@ void PlayerController::attack() // For now - nothing } +} } /* namespace controller */ } /* namespace farmlands */ diff --git a/src/controller/PlayerController.h b/src/controller/player/PlayerController.h similarity index 91% rename from src/controller/PlayerController.h rename to src/controller/player/PlayerController.h index f176f8f..3e416d2 100644 --- a/src/controller/PlayerController.h +++ b/src/controller/player/PlayerController.h @@ -10,14 +10,13 @@ #include #include +#include + #include namespace farmlands { - -// Forward declarations -struct GameState; - namespace controller { +namespace player { class PlayerController : public base::Component { @@ -38,10 +37,12 @@ namespace controller { base::Transform* m_transform; uint32_t m_attackTimeLeft; - float m_vx, m_vy; + model::Direction m_facingDirection; + bool m_walking, m_running; }; +} } /* namespace controller */ } /* namespace farmlands */ diff --git a/src/graphics/BackgroundRenderer.cpp b/src/graphics/BackgroundRenderer.cpp index 329bffb..75b9232 100644 --- a/src/graphics/BackgroundRenderer.cpp +++ b/src/graphics/BackgroundRenderer.cpp @@ -22,8 +22,8 @@ namespace farmlands { namespace graphics { BackgroundRenderer::BackgroundRenderer() - : level(nullptr), - m_context(nullptr) + : m_context(nullptr), + m_back(nullptr) { } @@ -36,6 +36,7 @@ void BackgroundRenderer::onInitialize() Assert(gameObject != nullptr, "Component not properly initialized!"); m_context = &GameState::current().renderContext; + m_back = gameObject->component(); } void BackgroundRenderer::onRender() @@ -53,21 +54,21 @@ void BackgroundRenderer::onRender() int maxCellY = ceilf(m_context->cameraTransform()->y + cellsOnScreenY / 2); // Clamp cell positions - minCellX = clamp(minCellX, 0, (int)level->columnCount() - 1); - maxCellX = clamp(maxCellX, 0, (int)level->columnCount() - 1); - minCellY = clamp(minCellY, 0, (int)level->rowCount() - 1); - maxCellY = clamp(maxCellY, 0, (int)level->rowCount() - 1); + minCellX = clamp(minCellX, 0, (int)m_back->columnCount() - 1); + maxCellX = clamp(maxCellX, 0, (int)m_back->columnCount() - 1); + minCellY = clamp(minCellY, 0, (int)m_back->rowCount() - 1); + maxCellY = clamp(maxCellY, 0, (int)m_back->rowCount() - 1); // Draw each layer - for (size_t i = 0; i < level->layerCount(); i++) + for (size_t i = 0; i < m_back->layerCount(); i++) { - int textureId = level->texture(i); + resources::ResourceId textureId = m_back->texture(i); // Render only visible tiles for (int y = minCellY; y <= maxCellY; y++) for (int x = minCellX; x <= maxCellX; x++) { - int cellId = level->cell(i, y, x); + int cellId = m_back->cell(i, y, x); // Obtain texture SDL_Texture* texture = ResourceManager::instance().texture(textureId); diff --git a/src/graphics/BackgroundRenderer.h b/src/graphics/BackgroundRenderer.h index 0d9087a..8a6f443 100644 --- a/src/graphics/BackgroundRenderer.h +++ b/src/graphics/BackgroundRenderer.h @@ -11,7 +11,8 @@ #include #include #include -#include +#include +#include namespace farmlands { namespace graphics { @@ -25,14 +26,12 @@ public: virtual void onInitialize() override; virtual void onRender() override; - // Public fields - model::Level* level; - private: void getCell(SDL_Texture* texture, uint32_t cell, int* outX, int* outY); // Private fields base::RenderContext* m_context; + model::Background* m_back; }; } /* namespace graphics */ diff --git a/src/graphics/SpriteRenderer.cpp b/src/graphics/SpriteRenderer.cpp index f79b02f..bbeeab7 100644 --- a/src/graphics/SpriteRenderer.cpp +++ b/src/graphics/SpriteRenderer.cpp @@ -13,6 +13,7 @@ #include using namespace farmlands::graphics::backend; +using namespace farmlands::resources; namespace farmlands { namespace graphics { @@ -66,7 +67,10 @@ void SpriteRenderer::onRender() void SpriteRenderer::onPostRender() { - sprite->advanceTime(1); + float animFps = GameState::current().config->animationFps; + float deltaTime = GameState::current().elapsedTime; + + sprite->advanceTime(animFps * deltaTime); } void SpriteRenderer::getCell(SDL_Texture* texture, uint32_t cell, int* outX, int* outY) diff --git a/src/gui/widgets/TextArea.cpp b/src/gui/widgets/TextArea.cpp index 8188af4..a9910a4 100644 --- a/src/gui/widgets/TextArea.cpp +++ b/src/gui/widgets/TextArea.cpp @@ -171,7 +171,7 @@ void TextArea::wrapText(TTF_Font* font) m_wrappedText = m_text + " "; // Process characters - for (int i = 0; i < m_wrappedText.size(); i++) + for (int i = 0; i < (int)m_wrappedText.size(); i++) { // Remove unwanted character if (m_wrappedText[i] == '\r') diff --git a/src/input/GameKey.h b/src/input/GameKey.h index 683000e..f126888 100644 --- a/src/input/GameKey.h +++ b/src/input/GameKey.h @@ -13,20 +13,37 @@ namespace input { enum GameKey { + // Movement Right, Up, Left, Down, - - Action, - Action2, Run, + // Actions + Action, + Action2, + + // Alternative move keys AltRight, AltUp, AltLeft, AltDown, + // Inventory + InventoryToggle, + Inventory1, + Inventory2, + Inventory3, + Inventory4, + Inventory5, + Inventory6, + Inventory7, + Inventory8, + Inventory9, + Inventory10, + + // Debug keys Debug_ZoomIn, Debug_ZoomOut, diff --git a/src/input/GameKeyConfiguration.cpp b/src/input/GameKeyConfiguration.cpp index 36a43a1..1c1e1c0 100644 --- a/src/input/GameKeyConfiguration.cpp +++ b/src/input/GameKeyConfiguration.cpp @@ -17,20 +17,37 @@ namespace input { { .keys = { + // Movement SDL_SCANCODE_RIGHT, // Right SDL_SCANCODE_UP, // Up SDL_SCANCODE_LEFT, // Left SDL_SCANCODE_DOWN, // Down - - SDL_SCANCODE_SPACE, // Action - SDL_SCANCODE_LCTRL, // Action2 SDL_SCANCODE_LSHIFT, // Run + // Action keys + SDL_SCANCODE_SPACE, // Action + SDL_SCANCODE_LCTRL, // Action2 + + // Alternative movement SDL_SCANCODE_D, // AltRight SDL_SCANCODE_W, // AltUp SDL_SCANCODE_A, // AltLeft SDL_SCANCODE_S, // AltRight + // Inventory + SDL_SCANCODE_I, // InventoryToggle + SDL_SCANCODE_1, // Inventory1 + SDL_SCANCODE_2, // Inventory2 + SDL_SCANCODE_3, // Inventory3 + SDL_SCANCODE_4, // Inventory4 + SDL_SCANCODE_5, // Inventory5 + SDL_SCANCODE_6, // Inventory6 + SDL_SCANCODE_7, // Inventory7 + SDL_SCANCODE_8, // Inventory8 + SDL_SCANCODE_9, // Inventory9 + SDL_SCANCODE_0, // Inventory10 + + // Debug SDL_SCANCODE_KP_PLUS, // Debug_ZoomIn, SDL_SCANCODE_KP_MINUS, // Debug_ZoomOut, } diff --git a/src/model/Background.cpp b/src/model/Background.cpp new file mode 100644 index 0000000..cb89132 --- /dev/null +++ b/src/model/Background.cpp @@ -0,0 +1,61 @@ +/* + * Background.cpp + * + * Created on: Dec 1, 2016 + * Author: tibi + */ + +#include +#include + +namespace farmlands { +namespace model { + + +Background::Background(size_t layerCount, size_t rowCount, size_t columnCount) + : m_cells(new Cell[layerCount * rowCount * columnCount]), + m_textures(new resources::ResourceId[layerCount]), + m_layers(layerCount), + m_rows(rowCount), + m_columns(columnCount) +{ +} + +Background::~Background() +{ + delete[] m_cells; + delete[] m_textures; +} + +Cell Background::cell(size_t layer, size_t row, size_t col) const +{ + Assert(layer < m_layers, "Layer out of bounds."); + Assert(row < m_rows, "Row out of bounds."); + Assert(col < m_columns, "Column out of bounds."); + + return m_cells[layer * m_rows * m_columns + row * m_columns + col]; +} + +void Background::setCell(size_t layer, size_t row, size_t col, Cell value) +{ + Assert(layer < m_layers, "Layer out of bounds."); + Assert(row < m_rows, "Row out of bounds."); + Assert(col < m_columns, "Column out of bounds."); + + m_cells[layer * m_rows * m_columns + row * m_columns + col] = value; +} + +resources::ResourceId Background::texture(size_t layer) const +{ + Assert(layer < m_layers, "Layer out of bounds."); + return m_textures[layer]; +} + +void Background::setTexture(size_t layer, resources::ResourceId textureId) const +{ + Assert(layer < m_layers, "Layer out of bounds."); + m_textures[layer] = textureId; +} + +} /* namespace model */ +} /* namespace farmlands */ diff --git a/src/model/Level.h b/src/model/Background.h similarity index 52% rename from src/model/Level.h rename to src/model/Background.h index 14b7fdb..f3145d4 100644 --- a/src/model/Level.h +++ b/src/model/Background.h @@ -1,29 +1,26 @@ /* - * Level.h + * Background.h * - * Created on: Nov 11, 2016 + * Created on: Dec 1, 2016 * Author: tibi */ -#ifndef MODEL_LEVEL_H_ -#define MODEL_LEVEL_H_ +#ifndef MODEL_BACKGROUND_H_ +#define MODEL_BACKGROUND_H_ -#include -#include +#include +#include namespace farmlands { namespace model { typedef int16_t Cell; - class Level + class Background: public base::Component { public: - Level(size_t layerCount, size_t rowCount, size_t columnCount); - Level(const Level&) = delete; - Level& operator= (const Level&) = delete; - - virtual ~Level(); + Background(size_t layerCount, size_t rowCount, size_t columnCount); + virtual ~Background(); inline size_t layerCount() const { return m_layers; } inline size_t rowCount() const { return m_rows; } @@ -32,14 +29,12 @@ namespace model { Cell cell(size_t layer, size_t row, size_t col) const; void setCell(size_t layer, size_t row, size_t col, Cell value); - int texture(size_t layer) const; - void setTexture(size_t layer, int textureId) const; - - size_t m_cellWidth, m_cellHeight; + resources::ResourceId texture(size_t layer) const; + void setTexture(size_t layer, resources::ResourceId textureId) const; private: Cell* m_cells; - int* m_textures; + resources::ResourceId* m_textures; size_t m_layers; size_t m_rows; size_t m_columns; @@ -48,4 +43,4 @@ namespace model { } /* namespace model */ } /* namespace farmlands */ -#endif /* MODEL_LEVEL_H_ */ +#endif /* MODEL_BACKGROUND_H_ */ diff --git a/src/model/Configuration.h b/src/model/Configuration.h index 6639a61..08b075d 100644 --- a/src/model/Configuration.h +++ b/src/model/Configuration.h @@ -4,37 +4,20 @@ * Created on: Nov 13, 2016 * Author: tibi */ +#ifndef MODEL_CONFIGURATION_H_ +#define MODEL_CONFIGURATION_H_ #include namespace farmlands { namespace model { - struct KeyConfiguration - { - SDL_Scancode Right = SDL_SCANCODE_RIGHT; - SDL_Scancode Up = SDL_SCANCODE_UP; - SDL_Scancode Left = SDL_SCANCODE_LEFT; - SDL_Scancode Down = SDL_SCANCODE_DOWN; - - SDL_Scancode AltRight = SDL_SCANCODE_D; - SDL_Scancode AltUp = SDL_SCANCODE_W; - SDL_Scancode AltLeft = SDL_SCANCODE_A; - SDL_Scancode AltDown = SDL_SCANCODE_S; - - SDL_Scancode Action = SDL_SCANCODE_SPACE; - SDL_Scancode Action2 = SDL_SCANCODE_LCTRL; - SDL_Scancode Run = SDL_SCANCODE_LSHIFT; - - SDL_Scancode Debug_ZoomIn = SDL_SCANCODE_KP_PLUS; - SDL_Scancode Debug_ZoomOut = SDL_SCANCODE_KP_MINUS; - }; - struct Configuration { - KeyConfiguration keys; + float animationFps = 60.0f; }; } } +#endif diff --git a/src/model/Level.cpp b/src/model/Level.cpp deleted file mode 100644 index 03d54cf..0000000 --- a/src/model/Level.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Level.cpp - * - * Created on: Nov 11, 2016 - * Author: tibi - */ - -#include "Level.h" -#include - -namespace farmlands { -namespace model { - -Level::Level(size_t layerCount, size_t rowCount, size_t columnCount) - : m_cellWidth(0), - m_cellHeight(0), - m_cells(new Cell[layerCount * rowCount * columnCount]), - m_textures(new int[layerCount]), - m_layers(layerCount), - m_rows(rowCount), - m_columns(columnCount) -{ -} - -Level::~Level() -{ - delete[] m_cells; - delete[] m_textures; -} - - -Cell Level::cell(size_t layer, size_t row, size_t col) const -{ - assert(layer < m_layers); - assert(row < m_rows); - assert(col < m_columns); - - return m_cells[layer * m_rows * m_columns + row * m_columns + col]; -} - -void Level::setCell(size_t layer, size_t row, size_t col, Cell value) -{ - assert(layer < m_layers); - assert(row < m_rows); - assert(col < m_columns); - - m_cells[layer * m_rows * m_columns + row * m_columns + col] = value; -} - -int Level::texture(size_t layer) const -{ - return m_textures[layer]; -} - -void Level::setTexture(size_t layer, int textureId) const -{ - m_textures[layer] = textureId; -} - -} /* namespace model */ -} /* namespace farmlands */ - diff --git a/src/model/Player.h b/src/model/Player.h deleted file mode 100644 index 67eff6d..0000000 --- a/src/model/Player.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Player.h - * - * Created on: Nov 26, 2016 - * Author: tibi - */ - -#ifndef MODEL_PLAYER_H_ -#define MODEL_PLAYER_H_ - -#include - -namespace farmlands { -namespace model { - -#define PLAYER_INVENTORY_SIZE 3*12 - - struct Player - { - float posX, posY; - float lastDeltaX, lastDeltaY; - Direction direction; - - bool attacking; - uint32_t attackTimeLeft; - - int inventorySelection = -1; - int inventory[PLAYER_INVENTORY_SIZE]; - }; - -} -} - - - -#endif /* MODEL_PLAYER_H_ */ diff --git a/src/resources/ResourceInfo.h b/src/resources/ResourceInfo.h index 61e44ae..2fd35e4 100644 --- a/src/resources/ResourceInfo.h +++ b/src/resources/ResourceInfo.h @@ -15,10 +15,13 @@ namespace resources { { None, Texture, - Sprite, - Level, - LevelLayer, Font, + Sprite, + Configuration, + Scene, + Background, + BackgroundLayer, + Item, }; struct ResourceInfo diff --git a/src/resources/ResourceManager.cpp b/src/resources/ResourceManager.cpp new file mode 100644 index 0000000..1aba72e --- /dev/null +++ b/src/resources/ResourceManager.cpp @@ -0,0 +1,162 @@ +/* + * ResourceManager.cpp + * + * Created on: Nov 7, 2016 + * Author: tibi + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#define FONTID(id,size) (id * 1000 + size) +#define FONTID_SIZE(fontid) (fontid % 1000) +#define FONTID_ID(fontid) (fontid / 1000) + +using namespace farmlands::graphics::backend; + +namespace farmlands { +namespace resources { + +ResourceManager ResourceManager::s_instance; + +ResourceManager& ResourceManager::instance() +{ + return s_instance; +} + +ResourceManager::ResourceManager() + : m_loadedResources(new LoadedResource[sizeof(RInfo) / sizeof(RInfo[0])]) +{ + for(size_t i = 0; i < sizeof(RInfo) / sizeof(RInfo[0]); i++) + m_loadedResources[i].loaded = false; +} + +ResourceManager::~ResourceManager() +{ + // Unload resources + for(size_t i = 0; i < sizeof(RInfo) / sizeof(RInfo[0]); i++) + { + if (m_loadedResources[i].loaded) + { + switch(RInfo[i].type) + { + case ResourceType::Texture: + SDL_DestroyTexture(m_loadedResources[i].texture.texture); + SDL_FreeSurface(m_loadedResources[i].texture.surface); + break; + + default: + std::cerr << "Warning: Cannot free resource " << i << " of type " << (int)RInfo[i].type << "\n"; + break; + } + } + } + + delete[] m_loadedResources; + + // Unload fonts + for (auto pair : m_fontCache) + { + TTF_CloseFont(pair.second); + } +} + +void ResourceManager::initialize() +{ +} + +void ResourceManager::loadMainMenu() +{ +} + +void ResourceManager::loadGame() +{ + GameState::current().config = storage::parse(R::Config::Default); + GameState::current().scene = storage::parse(R::Scenes::Game); + GameState::current().scene->root.onCreate(); +} + +std::string ResourceManager::getPath(ResourceId resourceId) +{ + Assert(resourceId >= 0 && resourceId < sizeof(RInfo) / sizeof(RInfo[0]), "Resource id out of bounds."); + + boost::filesystem::path resPath(ASSETS_DIR); + resPath.append(RInfo[resourceId].path); + + return resPath.native(); +} + +ResourceId ResourceManager::getId(std::string resPathStr) +{ + boost::filesystem::path resPath(resPathStr); + + for(size_t i = 0; i < sizeof(RInfo) / sizeof(RInfo[0]); i++) + { + boost::filesystem::path iPath (RInfo[i].path); + if (resPath == iPath) + return i; + } + + return (ResourceId)-1; +} + +TTF_Font* ResourceManager::font(ResourceId fontId, int pointSize) +{ + Assert(RInfo[fontId].type == ResourceType::Font, "Resource must be a font"); + + // Do not load if already loaded + auto it = m_fontCache.find(FONTID(fontId, pointSize)); + if (it != m_fontCache.end()) + return it->second; + + // Open font + std::string fontPath = getPath(fontId); + TTF_Font* font = TTF_OpenFont(fontPath.c_str(), pointSize); + if (!font) + THROW(utils::ResourceLoadException, "Could not load font " + fontPath); + + // Cache font + m_fontCache.emplace(FONTID(fontId, pointSize), font); + + return font; +} + +SDL_Texture* ResourceManager::texture(ResourceId textureId) +{ + Assert(RInfo[textureId].type == ResourceType::Texture, "Resource must be a texture"); + + // See if already loaded + if (!m_loadedResources[textureId].loaded) + { + // Open file + std::string texturePath = getPath(textureId); + SDL_Surface* surface = IMG_Load(texturePath.c_str()); + if (surface == NULL) + THROW(utils::ResourceLoadException, "Failed to load texture " + texturePath); + + SDL_Texture* texture = SDL_CreateTextureFromSurface(SdlRenderer::instance().internalRenderer(), surface); + if (texture == NULL) + THROW(utils::ResourceLoadException, "Failed to create texture " + texturePath); + + // Add to loaded resources + m_loadedResources[textureId].texture.surface = surface; + m_loadedResources[textureId].texture.texture = texture; + m_loadedResources[textureId].loaded = true; + } + + return m_loadedResources[textureId].texture.texture; +} + + +} /* namespace storage */ +} /* namespace farmlands */ + + diff --git a/src/resources/ResourceManager.h b/src/resources/ResourceManager.h index 13a641b..dd1430d 100644 --- a/src/resources/ResourceManager.h +++ b/src/resources/ResourceManager.h @@ -9,7 +9,6 @@ #define STORAGE_RESOURCEMANAGER_H_ #include -#include #include #include @@ -30,7 +29,6 @@ namespace resources { struct LoadedResource { bool loaded; - union { struct @@ -38,9 +36,6 @@ namespace resources { SDL_Surface* surface; SDL_Texture* texture; } texture; - - model::Level* level; - base::Sprite* sprite; }; }; @@ -52,20 +47,12 @@ namespace resources { static ResourceManager& instance(); ~ResourceManager(); - void initialize(); - // Loading routines + void initialize(); void loadMainMenu(); - void loadGameAssets(); - void loadLevel(ResourceId levelId); + void loadGame(); - TTF_Font* font(ResourceId id, int pointSize); - SDL_Texture* texture(ResourceId id); - model::Level* level(ResourceId id); - base::Sprite* sprite(ResourceId id); - - private: - ResourceManager(); + // Getters /** * Obtains the path of the resource in native format. @@ -76,20 +63,22 @@ namespace resources { * Obtains the id of a resource based on its path. * Returns: the resource id, or -1 if resource not found. */ - int getId(std::string resourcePath); + ResourceId getId(std::string resourcePath); - void loadFont(ResourceId fontId, int pointSize); - void loadTexture(ResourceId textureId); - void loadSprite(ResourceId spriteId); - void loadLevelLayer(model::Level* level, size_t layerNumber, ResourceId resourceId); + // Resource getters + TTF_Font* font(ResourceId id, int pointSize); + SDL_Texture* texture(ResourceId id); + private: + ResourceManager(); + + typedef int FontId; + + // Instance static ResourceManager s_instance; // Loaded resources LoadedResource* m_loadedResources; - - typedef int FontId; - std::map m_fontCache; }; diff --git a/src/resources/ResourceManager/ResourceManager.cpp b/src/resources/ResourceManager/ResourceManager.cpp deleted file mode 100644 index 7dc2831..0000000 --- a/src/resources/ResourceManager/ResourceManager.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * ResourceManager.cpp - * - * Created on: Nov 7, 2016 - * Author: tibi - */ - -#include -#include -#include - -#include - -namespace farmlands { -namespace resources { - -ResourceManager ResourceManager::s_instance; - -ResourceManager& ResourceManager::instance() -{ - return s_instance; -} - -ResourceManager::ResourceManager() - : m_loadedResources(new LoadedResource[sizeof(RInfo) / sizeof(RInfo[0])]) -{ - for(size_t i = 0; i < sizeof(RInfo) / sizeof(RInfo[0]); i++) - m_loadedResources[i].loaded = false; -} - -ResourceManager::~ResourceManager() -{ - // Unload resources - for(size_t i = 0; i < sizeof(RInfo) / sizeof(RInfo[0]); i++) - { - if (m_loadedResources[i].loaded) - { - switch(RInfo[i].type) - { - case ResourceType::Level: - delete m_loadedResources[i].level; - break; - - case ResourceType::Texture: - SDL_DestroyTexture(m_loadedResources[i].texture.texture); - SDL_FreeSurface(m_loadedResources[i].texture.surface); - break; - - case ResourceType::Sprite: - delete m_loadedResources[i].sprite; - - default: - Assert(false, "Cannot free resources!"); - break; - } - } - } - - delete[] m_loadedResources; -} - -void ResourceManager::initialize() -{ -} - -void ResourceManager::loadMainMenu() -{ -} - -void ResourceManager::loadGameAssets() -{ - loadSprite(R::Sprites::Player); -} - -std::string ResourceManager::getPath(ResourceId resourceId) -{ - Assert(resourceId >= 0 && resourceId < sizeof(RInfo) / sizeof(RInfo[0]), "Resource id out of bounds."); - - boost::filesystem::path resPath(ASSETS_DIR); - resPath.append(RInfo[resourceId].path); - - return resPath.native(); -} - -int ResourceManager::getId(std::string resPathStr) -{ - boost::filesystem::path resPath(resPathStr); - - for(size_t i = 0; i < sizeof(RInfo) / sizeof(RInfo[0]); i++) - { - boost::filesystem::path iPath (RInfo[i].path); - if (resPath == iPath) - return (int)i; - } - - return -1; -} - -} /* namespace storage */ -} /* namespace farmlands */ - - diff --git a/src/resources/ResourceManager/ResourceManager_Fonts.cpp b/src/resources/ResourceManager/ResourceManager_Fonts.cpp deleted file mode 100644 index 0d72096..0000000 --- a/src/resources/ResourceManager/ResourceManager_Fonts.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* - * ResourceManager_Fonts.cpp - * - * Created on: Nov 29, 2016 - * Author: tibi - */ -#include -#include - -#define FONTID(id,size) (id * 1000 + size) -#define FONTID_SIZE(fontid) (fontid % 1000) -#define FONTID_ID(fontid) (fontid / 1000) - -namespace farmlands { -namespace resources { - -TTF_Font* ResourceManager::font(ResourceId id, int pointSize) -{ - // Open from cache - auto it = m_fontCache.find(FONTID(id, pointSize)); - if (it != m_fontCache.end()) - return it->second; - - // Open font - std::string fontPath = getPath(id); - TTF_Font* font = TTF_OpenFont(fontPath.c_str(), pointSize); - if (!font) - THROW(utils::ResourceLoadException, "Could not load font " + fontPath); - - // Cache it - m_fontCache.emplace(FONTID(id, pointSize), font); - - return font; -} - -} -} diff --git a/src/resources/ResourceManager/ResourceManager_Levels.cpp b/src/resources/ResourceManager/ResourceManager_Levels.cpp deleted file mode 100644 index df79b77..0000000 --- a/src/resources/ResourceManager/ResourceManager_Levels.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - * ResourceManager_Levels.cpp - * - * Created on: Nov 11, 2016 - * Author: tibi - */ - -#include -#include -#include - -#include -#include - -#include - -using namespace nlohmann; - -namespace farmlands { -namespace resources { - -void ResourceManager::loadLevelLayer(model::Level* level, size_t layer, ResourceId resourceId) -{ - Assert(RInfo[resourceId].type == ResourceType::LevelLayer, "Resource must be a level layer."); - - char buffer[1024 * 10]; - - // Open file - std::string pathIn = getPath(resourceId); - std::ifstream in(pathIn); - if (!in) - THROW(utils::ResourceLoadException, "Could not load level layer " + pathIn); - - // Read CSV file line by line - for (size_t row = 0; row < level->rowCount(); row++) - { - in.getline(buffer, sizeof(buffer)); - - if (in.eof()) - THROW(utils::ResourceLoadException, "Unexpected end of file " + pathIn); - - // Separated by comma (or maybe semicolon) - char* nextNum = strtok(buffer, ",;"); - for (size_t col = 0; col < level->columnCount() && nextNum != NULL; col++) - { - model::Cell cell = (model::Cell)strtol(nextNum, NULL, 10); - level->setCell(layer, row, col, cell); - - nextNum = strtok(NULL, ",;"); - } - } - - in.close(); -} - - -void ResourceManager::loadLevel(ResourceId levelId) -{ - // Sanity checks - Assert(RInfo[levelId].type == ResourceType::Level, "Resource must be a level!"); - if (m_loadedResources[levelId].loaded) - return; - - // Open file - std::string levelPath = getPath(levelId); - std::ifstream levelIn(getPath(levelId)); - if (!levelIn) - THROW(utils::ResourceLoadException, "Failed to load level " + levelPath); - - // Parse file - json levelJs; - levelIn>>levelJs; - - size_t layerCount = levelJs.value("layerCount", 0u); - size_t rowCount = levelJs.value("height", 0u); - size_t colCount = levelJs.value("width", 0u); - - assert(layerCount > 0 && rowCount > 0 && colCount > 0); - model::Level* level = new model::Level(layerCount, rowCount, colCount); - - level->m_cellWidth = levelJs.value("cellWidth", 0u); - level->m_cellHeight = levelJs.value("cellHeight", 0u); - - // Read layers - json layersJs = levelJs["layers"]; - size_t layer = 0; - - for (auto it = layersJs.begin(); it != layersJs.end(); it++, layer++) - { - std::string cellsFileName = it->value("cellsFile", std::string()); - loadLevelLayer(level, layer, getId(cellsFileName)); - - std::string textureFileName = it->value("textureFile", std::string()); - int textureId = getId(textureFileName); - level->setTexture(layer, textureId); - loadTexture(textureId); - } - - m_loadedResources[levelId].loaded = true; - m_loadedResources[levelId].level = level; -} - -model::Level* ResourceManager::level(ResourceId id) -{ - Assert(RInfo[id].type == ResourceType::Level, "Resource must be a level!"); - - return m_loadedResources[id].level; -} - -} -} - - - diff --git a/src/resources/ResourceManager/ResourceManager_Sprites.cpp b/src/resources/ResourceManager/ResourceManager_Sprites.cpp deleted file mode 100644 index 691e6c1..0000000 --- a/src/resources/ResourceManager/ResourceManager_Sprites.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - * ResourceManager_Sprites.cpp - * - * Created on: Nov 29, 2016 - * Author: tibi - */ -#include -#include -#include -#include - -#include -#include - -#include - -using namespace nlohmann; -using namespace farmlands::base; - -namespace farmlands { -namespace resources { - - -void ResourceManager::loadSprite(ResourceId spriteId) -{ - Assert(RInfo[spriteId].type == ResourceType::Sprite, "Resource must be a sprite!"); - if (m_loadedResources[spriteId].loaded) - return; - - // Open file - std::string spritePath = getPath(spriteId); - std::ifstream spriteIn(spritePath); - if (!spriteIn) - THROW(utils::ResourceLoadException, "Could not load " + spritePath); - - // Parse file - json spriteJs; - spriteIn >> spriteJs; - - Sprite* sprite = new Sprite(); - sprite->anchorX = spriteJs.value("anchorX", 0.0f); - sprite->anchorY = spriteJs.value("anchorY", 0.0f); - - json statesJs = spriteJs.at("states"); - - for (auto state : statesJs) - { - SpriteState spriteState; - spriteState.name = state.value("name", std::string()); - - // Obtain frames - json framesJs = state.at("frames"); - for (auto frame : framesJs) - { - Frame spriteFrame; - spriteFrame.tileSetCell = frame.value("cell", 0u); - spriteFrame.width = frame.value("width", 0u); - spriteFrame.height = frame.value("height", 0u); - spriteFrame.duration = frame.value("duration", 0u); - - // Obtain tile set id - std::string tileSetPath = frame.value("tileSet", std::string()); - spriteFrame.tileSetId = getId(tileSetPath); - loadTexture(spriteFrame.tileSetId); - - // Add frame - spriteState.frames.push_back(spriteFrame); - } - - // Add state - sprite->addState(spriteState); - } - - m_loadedResources[spriteId].loaded = true; - m_loadedResources[spriteId].sprite = sprite; -} - -Sprite* ResourceManager::sprite(ResourceId id) -{ - Assert(RInfo[id].type == ResourceType::Sprite, "Resource must be a sprite!"); - - return m_loadedResources[id].sprite; -} - -} -} - - - - - - diff --git a/src/resources/ResourceManager/ResourceManager_Textures.cpp b/src/resources/ResourceManager/ResourceManager_Textures.cpp deleted file mode 100644 index ed69624..0000000 --- a/src/resources/ResourceManager/ResourceManager_Textures.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * ResourceManager_Textures.cpp - * - * Created on: Nov 12, 2016 - * Author: tibi - */ - -#include -#include -#include -#include - -using namespace farmlands::graphics::backend; - -namespace farmlands { -namespace resources { - -void ResourceManager::loadTexture(ResourceId resourceId) -{ - Assert(RInfo[resourceId].type == ResourceType::Texture, "Resource must be a texture!"); - if (m_loadedResources[resourceId].loaded) - return; - - // Open file - std::string texturePath = getPath(resourceId); - SDL_Surface* surface = IMG_Load(texturePath.c_str()); - if (surface == NULL) - THROW(utils::ResourceLoadException, "Failed to load texture " + texturePath); - - SDL_Texture* texture = SDL_CreateTextureFromSurface(SdlRenderer::instance().internalRenderer(), surface); - if (texture == NULL) - THROW(utils::ResourceLoadException, "Failed to create texture " + texturePath); - - // Add to loaded resources - m_loadedResources[resourceId].loaded = true; - m_loadedResources[resourceId].texture.surface = surface; - m_loadedResources[resourceId].texture.texture = texture; -} - -SDL_Texture* ResourceManager::texture(ResourceId id) -{ - Assert(RInfo[id].type == ResourceType::Texture, "Resource must be a texture!"); - - return m_loadedResources[id].texture.texture; -} - -} -} - - - - - - - diff --git a/src/resources/Resources.g.h b/src/resources/Resources.g.h index 208a291..53eae4a 100644 --- a/src/resources/Resources.g.h +++ b/src/resources/Resources.g.h @@ -15,44 +15,70 @@ namespace resources { enum Sprites { Player = 0, + items_Lvl1_sword = 1, + items_Stone_pickaxe = 2, + }; + enum Scenes + { + Game = 3, }; enum Fonts { - DejaVuSans = 1, + DejaVuSans = 4, }; enum Tilesets { - PlayerTiles = 2, - Ground = 3, + PlayerTiles = 5, + Ground = 6, }; enum Ui { - Cursor = 4, + Mini_inventory = 7, + Cursor = 8, }; enum Levels { - Farm_Background = 5, - Farm = 6, + Farm_Background = 9, + Farm = 10, + }; + enum Config + { + Default = 11, + }; + enum Items + { + Stone_pickaxe = 12, + Lvl1_sword = 13, }; } const int RInfo_Sprites_Begin = 0; - const int RInfo_Fonts_Begin = 1; - const int RInfo_Tilesets_Begin = 2; - const int RInfo_Ui_Begin = 4; - const int RInfo_Levels_Begin = 5; + const int RInfo_Scenes_Begin = 3; + const int RInfo_Fonts_Begin = 4; + const int RInfo_Tilesets_Begin = 5; + const int RInfo_Ui_Begin = 7; + const int RInfo_Levels_Begin = 9; + const int RInfo_Config_Begin = 11; + const int RInfo_Items_Begin = 12; /** * This array contains the names of all the files, and the corresponding file type. */ const ResourceInfo RInfo[] = { - { "sprites/player.sprite", ResourceType::Sprite }, + { "sprites/Player.sprite", ResourceType::Sprite }, + { "sprites/items/lvl1_sword.sprite", ResourceType::Sprite }, + { "sprites/items/stone_pickaxe.sprite", ResourceType::Sprite }, + { "scenes/Game.scene", ResourceType::Scene }, { "fonts/DejaVuSans.ttf", ResourceType::Font }, { "tilesets/PlayerTiles.png", ResourceType::Texture }, { "tilesets/Ground.png", ResourceType::Texture }, + { "ui/mini_inventory.png", ResourceType::Texture }, { "ui/cursor.png", ResourceType::Texture }, - { "levels/Farm_Background.csv", ResourceType::LevelLayer }, - { "levels/Farm.level", ResourceType::Level }, + { "levels/Farm_Background.csv", ResourceType::BackgroundLayer }, + { "levels/Farm.back", ResourceType::Background }, + { "config/Default.config", ResourceType::Configuration }, + { "items/stone_pickaxe.item", ResourceType::Item }, + { "items/lvl1_sword.item", ResourceType::Item }, }; } diff --git a/src/storage/Parse.cpp b/src/storage/Parse.cpp new file mode 100644 index 0000000..88ee0bf --- /dev/null +++ b/src/storage/Parse.cpp @@ -0,0 +1,10 @@ +#include + +namespace farmlands { +namespace storage { + +DEFINE_EXCEPTION_CPP(ParserException, utils::Exception); + +} +} + diff --git a/src/storage/Parse.h b/src/storage/Parse.h new file mode 100644 index 0000000..c8c11e7 --- /dev/null +++ b/src/storage/Parse.h @@ -0,0 +1,87 @@ +/* + * Parsers.h + * + * Created on: Dec 1, 2016 + * Author: tibi + */ + +#ifndef STORAGE_PARSE_H_ +#define STORAGE_PARSE_H_ + +#include +#include + +#include +#include + +namespace farmlands { +namespace storage { + +/****** Declarations ******/ + + DEFINE_EXCEPTION_CLASS(ParserException, utils::Exception); + + /** + * Parses a resource using a resource ID. + */ + template + T* parse(resources::ResourceId resourceId); + + /** + * Parses a resource using a file path. + */ + template + T* parse(std::string filePath); + + /** + * Parses a resource from a property tree. + */ + template + T* parse(boost::property_tree::ptree& root); + + +/****** Implementations ******/ + + + template + T* parse(resources::ResourceId resourceId) + { + // Get resource file + std::string path = resources::ResourceManager::instance().getPath(resourceId); + + // Parse the tree + return parse(path); + } + + template + T* parse(std::string path) + { + // Open file + std::ifstream resourceIn(path); + if (!resourceIn) + THROW(utils::ResourceLoadException, "Failed to load resource " + path); + + // Read property tree + boost::property_tree::ptree tree; + boost::property_tree::read_xml(resourceIn, tree); + resourceIn.close(); + + // Parse the tree (give root element) + return parse(tree); + } + + template + T* parse(boost::property_tree::ptree& root) + { + std::string typeName = typeid(T).name(); + + // Throw not implemented exception + THROW(utils::NotImplementedException, "No parser implemented for type " + typeName); + } + +} +} + + + +#endif /* STORAGE_PARSE_H_ */ diff --git a/src/storage/Parsers.h b/src/storage/Parsers.h new file mode 100644 index 0000000..10ca2d6 --- /dev/null +++ b/src/storage/Parsers.h @@ -0,0 +1,22 @@ +/* + * Parsers.h + * + * Created on: Dec 1, 2016 + * Author: tibi + */ + +#ifndef STORAGE_PARSERS_PARSERS_H_ +#define STORAGE_PARSERS_PARSERS_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#endif /* STORAGE_PARSERS_PARSERS_H_ */ diff --git a/src/storage/parsers/ParseComponents_base.cpp b/src/storage/parsers/ParseComponents_base.cpp new file mode 100644 index 0000000..0ee912b --- /dev/null +++ b/src/storage/parsers/ParseComponents_base.cpp @@ -0,0 +1,39 @@ +/* + * ParseComponents_base.cpp + * + * Created on: Dec 1, 2016 + * Author: tibi + */ + +#include + +namespace farmlands { +namespace storage { + +template <> +base::Transform* parse (boost::property_tree::ptree& root) +{ + // Ensure we are on the scene node (property tree seems to add root of its own) + if (root.front().first == "Transform") + root = root.front().second; + + base::Transform* transform = new base::Transform(); + transform->x = root.get(".x", 0.0f); + transform->y = root.get(".y", 0.0f); + return transform; +} + +template <> +base::Camera* parse (boost::property_tree::ptree& root) +{ + if (root.front().first == "Camera") + root = root.front().second; + + base::Camera* camera = new base::Camera(); + camera->scale = root.get(".scale", 1.0f); + camera->mainCamera = root.get(".mainCamera", false); + return camera; +} + +} +} diff --git a/src/storage/parsers/ParseComponents_base.h b/src/storage/parsers/ParseComponents_base.h new file mode 100644 index 0000000..48b2645 --- /dev/null +++ b/src/storage/parsers/ParseComponents_base.h @@ -0,0 +1,27 @@ +/* + * ParseGameObject.h + * + * Created on: Dec 1, 2016 + * Author: tibi + */ + +#ifndef STORAGE_PARSERS_PARSECOMPONENTS_BASE_H_ +#define STORAGE_PARSERS_PARSECOMPONENTS_BASE_H_ + +#include +#include +#include +#include + +namespace farmlands { +namespace storage { + + template <> + base::Transform* parse (boost::property_tree::ptree& root); + + template <> + base::Camera* parse (boost::property_tree::ptree& root); +} +} + +#endif /* STORAGE_PARSERS_PARSEGAMEOBJECT_H_ */ diff --git a/src/storage/parsers/ParseComponents_controller.cpp b/src/storage/parsers/ParseComponents_controller.cpp new file mode 100644 index 0000000..8087aeb --- /dev/null +++ b/src/storage/parsers/ParseComponents_controller.cpp @@ -0,0 +1,36 @@ +/* + * ParseComponents_controller.cpp + * + * Created on: Dec 1, 2016 + * Author: tibi + */ + +#include + +namespace farmlands { +namespace storage { + +template <> +controller::player::PlayerController* parse (boost::property_tree::ptree& root) +{ + // Ensure we are on the scene node (property tree seems to add root of its own) + if (root.front().first == "PlayerController") + root = root.front().second; + + controller::player::PlayerController* controller = new controller::player::PlayerController(); + return controller; +} + +template <> +controller::DebugController* parse (boost::property_tree::ptree& root) +{ + // Ensure we are on the scene node (property tree seems to add root of its own) + if (root.front().first == "DebugController") + root = root.front().second; + + controller::DebugController* controller = new controller::DebugController(); + return controller; +} + +} +} diff --git a/src/storage/parsers/ParseComponents_controller.h b/src/storage/parsers/ParseComponents_controller.h new file mode 100644 index 0000000..c65df2b --- /dev/null +++ b/src/storage/parsers/ParseComponents_controller.h @@ -0,0 +1,27 @@ +/* + * ParseComponents_controller.h + * + * Created on: Dec 1, 2016 + * Author: tibi + */ + +#ifndef STORAGE_PARSERS_PARSECOMPONENTS_CONTROLLER_H_ +#define STORAGE_PARSERS_PARSECOMPONENTS_CONTROLLER_H_ + +#include +#include +#include + +namespace farmlands { +namespace storage { + + template <> + controller::player::PlayerController* parse (boost::property_tree::ptree& root); + + template <> + controller::DebugController* parse (boost::property_tree::ptree& root); + +} +} + +#endif /* STORAGE_PARSERS_PARSECOMPONENTS_CONTROLLER_H_ */ diff --git a/src/storage/parsers/ParseComponents_graphics.cpp b/src/storage/parsers/ParseComponents_graphics.cpp new file mode 100644 index 0000000..272ce57 --- /dev/null +++ b/src/storage/parsers/ParseComponents_graphics.cpp @@ -0,0 +1,42 @@ +/* + * ParseComponents_graphics.cpp + * + * Created on: Dec 1, 2016 + * Author: tibi + */ + +#include + +namespace farmlands { +namespace storage { + +template <> +graphics::BackgroundRenderer* parse (boost::property_tree::ptree& root) +{ + // Ensure we are on the scene node (property tree seems to add root of its own) + if (root.front().first == "BackgroundRenderer") + root = root.front().second; + + graphics::BackgroundRenderer* renderer = new graphics::BackgroundRenderer(); + return renderer; +} + +template <> +graphics::SpriteRenderer* parse (boost::property_tree::ptree& root) +{ + // Ensure we are on the scene node (property tree seems to add root of its own) + if (root.front().first == "SpriteRenderer") + root = root.front().second; + + graphics::SpriteRenderer* renderer = new graphics::SpriteRenderer(); + + // Load sprite + std::string spritePath = root.get(".sprite"); + resources::ResourceId spriteId = resources::ResourceManager::instance().getId(spritePath); + renderer->sprite = parse(spriteId); + + return renderer; +} + +} +} diff --git a/src/storage/parsers/ParseComponents_graphics.h b/src/storage/parsers/ParseComponents_graphics.h new file mode 100644 index 0000000..da76a51 --- /dev/null +++ b/src/storage/parsers/ParseComponents_graphics.h @@ -0,0 +1,27 @@ +/* + * ParseComponents_graphics.h + * + * Created on: Dec 1, 2016 + * Author: tibi + */ + +#ifndef STORAGE_PARSERS_PARSECOMPONENTS_GRAPHICS_H_ +#define STORAGE_PARSERS_PARSECOMPONENTS_GRAPHICS_H_ + +#include +#include +#include + +namespace farmlands { +namespace storage { + + template <> + graphics::BackgroundRenderer* parse (boost::property_tree::ptree& root); + + template <> + graphics::SpriteRenderer* parse (boost::property_tree::ptree& root); + +} +} + +#endif /* STORAGE_PARSERS_PARSECOMPONENTS_GRAPHICS_H_ */ diff --git a/src/storage/parsers/ParseComponents_model.cpp b/src/storage/parsers/ParseComponents_model.cpp new file mode 100644 index 0000000..c0b4436 --- /dev/null +++ b/src/storage/parsers/ParseComponents_model.cpp @@ -0,0 +1,92 @@ +/* + * ParseComponents_model.cpp + * + * Created on: Dec 1, 2016 + * Author: tibi + */ +#include +#include + +using namespace farmlands::resources; + +namespace farmlands { +namespace storage { + +void parseBackgroundCells(resources::ResourceId cellsResource, model::Background* back, size_t layer) +{ + Assert(RInfo[cellsResource].type == ResourceType::BackgroundLayer, "Resource must be a level layer."); + + char buffer[1024 * 10]; + + // Open file + std::string pathIn = ResourceManager::instance().getPath(cellsResource); + std::ifstream in(pathIn); + if (!in) + THROW(utils::ResourceLoadException, "Could not load level layer " + pathIn); + + // Read CSV file line by line + for (size_t row = 0; row < back->rowCount(); row++) + { + in.getline(buffer, sizeof(buffer)); + + if (in.eof()) + THROW(utils::ResourceLoadException, "Unexpected end of file " + pathIn); + + // Separated by comma (or maybe semicolon) + char* nextNum = strtok(buffer, ",;"); + for (size_t col = 0; col < back->columnCount() && nextNum != NULL; col++) + { + model::Cell cell = (model::Cell)strtol(nextNum, NULL, 10); + back->setCell(layer, row, col, cell); + + nextNum = strtok(NULL, ",;"); + } + } + + in.close(); +} + +template <> +model::Background* parse (boost::property_tree::ptree& root) +{ + // Ensure we are on the scene node (property tree seems to add root of its own) + if (root.front().first == "Background") + root = root.front().second; + + // Read sizes + uint32_t layers = root.count("Layer"); + uint32_t rows = root.get(".rows"); + uint32_t cols = root.get(".columns"); + + // Create background object + model::Background* back = new model::Background(layers, rows, cols); + + // Read layers + size_t layerNum = 0; + for (auto layer : root) + { + if (layer.first == "Layer") + { + // Read cells + std::string cellsPath = layer.second.get(".cells"); + resources::ResourceId cellsId = resources::ResourceManager::instance().getId(cellsPath); + parseBackgroundCells(cellsId, back, layerNum); + + // Read texture name + std::string texPath = layer.second.get(".texture"); + resources::ResourceId tex = resources::ResourceManager::instance().getId(texPath); + back->setTexture(layerNum, tex); + + ++layerNum; + } + + } + + return back; +} + +} +} + + + diff --git a/src/storage/parsers/ParseComponents_model.h b/src/storage/parsers/ParseComponents_model.h new file mode 100644 index 0000000..7618257 --- /dev/null +++ b/src/storage/parsers/ParseComponents_model.h @@ -0,0 +1,27 @@ +/* + * ParseComponents_model.h + * + * Created on: Dec 1, 2016 + * Author: tibi + */ + +#ifndef STORAGE_PARSERS_PARSECOMPONENTS_MODEL_H_ +#define STORAGE_PARSERS_PARSECOMPONENTS_MODEL_H_ + +#include +#include + +namespace farmlands { +namespace storage { + + void parseBackgroundCells(resources::ResourceId cellsResource, model::Background* back, size_t layer); + + template <> + model::Background* parse (boost::property_tree::ptree& root); + +} +} + + + +#endif /* STORAGE_PARSERS_PARSECOMPONENTS_MODEL_H_ */ diff --git a/src/storage/parsers/ParseConfiguration.cpp b/src/storage/parsers/ParseConfiguration.cpp new file mode 100644 index 0000000..8b0e2e2 --- /dev/null +++ b/src/storage/parsers/ParseConfiguration.cpp @@ -0,0 +1,30 @@ +/* + * ParseConfiguration.cpp + * + * Created on: Dec 1, 2016 + * Author: tibi + */ + +#include +#include + +using namespace farmlands::resources; + +namespace farmlands { +namespace storage { + +template <> +model::Configuration* parse (boost::property_tree::ptree& root) +{ + // Ensure we are on the scene node (property tree seems to add root of its own) + if (root.front().first == "Configuration") + root = root.front().second; + + model::Configuration* config = new model::Configuration(); + config->animationFps = root.get("animationFps"); + + return config; +} + +} /* namespace storage */ +} /* namespace farmlands */ diff --git a/src/storage/parsers/ParseConfiguration.h b/src/storage/parsers/ParseConfiguration.h new file mode 100644 index 0000000..74b174e --- /dev/null +++ b/src/storage/parsers/ParseConfiguration.h @@ -0,0 +1,23 @@ +/* + * ParseConfiguration.h + * + * Created on: Dec 1, 2016 + * Author: tibi + */ + +#ifndef STORAGE_PARSERS_PARSECONFIGURATION_H_ +#define STORAGE_PARSERS_PARSECONFIGURATION_H_ + +#include +#include + +namespace farmlands { +namespace storage { + + template <> + model::Configuration* parse (boost::property_tree::ptree& root); + +} /* namespace storage */ +} /* namespace farmlands */ + +#endif /* STORAGE_PARSERS_PARSECONFIGURATION_H_ */ diff --git a/src/storage/parsers/ParseGameObject.cpp b/src/storage/parsers/ParseGameObject.cpp new file mode 100644 index 0000000..9166919 --- /dev/null +++ b/src/storage/parsers/ParseGameObject.cpp @@ -0,0 +1,61 @@ +/* + * ParseGameObject.cpp + * + * Created on: Dec 1, 2016 + * Author: tibi + */ +#include +#include + +namespace farmlands { +namespace storage { + + template <> + base::GameObject* parse (boost::property_tree::ptree& root) + { + // Ensure we are on the scene node (property tree seems to add root of its own) + if (root.front().first == "GameObject") + root = root.front().second; + + base::GameObject* gameObj = new base::GameObject(); + gameObj->name = root.get(".name"); + + for (auto child : root) + { + // Base objects + if (child.first == "Transform") + gameObj->addComponent(parse(child.second)); + + else if (child.first == "Camera") + gameObj->addComponent(parse(child.second)); + + // Model + else if (child.first == "Background") + { + std::string path = child.second.get(".src"); + resources::ResourceId id = resources::ResourceManager::instance().getId(path); + gameObj->addComponent(parse(id)); + } + + // Graphics + else if (child.first == "BackgroundRenderer") + gameObj->addComponent(parse(child.second)); + + else if (child.first == "SpriteRenderer") + gameObj->addComponent(parse(child.second)); + + // Controllers + else if (child.first == "PlayerController") + gameObj->addComponent(parse(child.second)); + + else if (child.first == "DebugController") + gameObj->addComponent(parse(child.second)); + + // !!! Add additional types here !!! + } + + return gameObj; + } + +} +} diff --git a/src/storage/parsers/ParseGameObject.h b/src/storage/parsers/ParseGameObject.h new file mode 100644 index 0000000..0465d0a --- /dev/null +++ b/src/storage/parsers/ParseGameObject.h @@ -0,0 +1,30 @@ +/* + * ParseGameObject.h + * + * Created on: Dec 1, 2016 + * Author: tibi + */ + +#ifndef STORAGE_PARSERS_PARSEGAMEOBJECT_H_ +#define STORAGE_PARSERS_PARSEGAMEOBJECT_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace farmlands { +namespace storage { + + template <> + base::GameObject* parse (boost::property_tree::ptree& root); + +} +} + +#endif /* STORAGE_PARSERS_PARSEGAMEOBJECT_H_ */ diff --git a/src/storage/parsers/ParseScene.cpp b/src/storage/parsers/ParseScene.cpp new file mode 100644 index 0000000..dc9018c --- /dev/null +++ b/src/storage/parsers/ParseScene.cpp @@ -0,0 +1,39 @@ +/* + * ParseScene.cpp + * + * Created on: Dec 1, 2016 + * Author: tibi + */ + +#include + + +namespace farmlands { +namespace storage { + +template <> +base::Scene* parse (boost::property_tree::ptree& root) +{ + // Ensure we are on the scene node (property tree seems to add root of its own) + if (root.front().first == "Scene") + root = root.front().second; + + base::Scene* scene = new base::Scene(); + scene->cellWidth = root.get(".cellWidth"); + scene->cellHeight = root.get(".cellHeight"); + + for (auto child : root) + { + if (child.first == "GameObject") + { + base::GameObject* obj = parse(child.second); + scene->root.addChild(obj); + } + } + + return scene; +} + +} +} + diff --git a/src/storage/parsers/ParseScene.h b/src/storage/parsers/ParseScene.h new file mode 100644 index 0000000..96e0042 --- /dev/null +++ b/src/storage/parsers/ParseScene.h @@ -0,0 +1,27 @@ +/* + * ParseScene.h + * + * Created on: Dec 1, 2016 + * Author: tibi + */ + +#ifndef STORAGE_PARSERS_PARSE_SCENE_H_ +#define STORAGE_PARSERS_PARSE_SCENE_H_ + +#include +#include +#include +#include + +namespace farmlands { +namespace storage { + + template <> + base::Scene* parse (boost::property_tree::ptree& root); + +} +} + + + +#endif /* STORAGE_PARSE_H_ */ diff --git a/src/storage/parsers/ParseSprite.cpp b/src/storage/parsers/ParseSprite.cpp new file mode 100644 index 0000000..6fafc59 --- /dev/null +++ b/src/storage/parsers/ParseSprite.cpp @@ -0,0 +1,84 @@ +/* + * ParseSprite.cpp + * + * Created on: Dec 1, 2016 + * Author: tibi + */ + +#include +#include + +namespace farmlands { +namespace storage { + + template <> + base::Frame* parse (boost::property_tree::ptree& root) + { + // Ensure we are on the scene node (property tree seems to add root of its own) + if (root.front().first == "Frame") + root = root.front().second; + + base::Frame* frame = new base::Frame(); + + // Obtine tile set id + std::string tileSetPath = root.get(".tileSet"); + frame->tileSetId = resources::ResourceManager::instance().getId(tileSetPath); + + // Set properties + frame->tileSetCell = root.get(".cell"); + frame->width = root.get(".w", 1u); + frame->height = root.get(".h", 1u); + frame->duration = root.get(".duration"); + + return frame; + } + + template <> + base::SpriteState* parse (boost::property_tree::ptree& root) + { + // Ensure we are on the scene node (property tree seems to add root of its own) + if (root.front().first == "SpriteState") + root = root.front().second; + + base::SpriteState* spriteState = new base::SpriteState(); + spriteState->name = root.get(".name"); + + for (auto child : root) + { + if (child.first == "Frame") + { + base::Frame* frame = parse(child.second); + spriteState->frames.push_back(*frame); + delete frame; + } + } + + return spriteState; + } + + template <> + base::Sprite* parse (boost::property_tree::ptree& root) + { + // Ensure we are on the scene node (property tree seems to add root of its own) + if (root.front().first == "Sprite") + root = root.front().second; + + base::Sprite* sprite = new base::Sprite(); + sprite->anchorX = root.get(".anchorX"); + sprite->anchorY = root.get(".anchorY"); + + for (auto child : root) + { + if (child.first == "State") + { + base::SpriteState* state = parse(child.second); + sprite->addState(*state); + delete state; + } + } + + return sprite; + } + +} +} diff --git a/src/storage/parsers/ParseSprite.h b/src/storage/parsers/ParseSprite.h new file mode 100644 index 0000000..a6edf59 --- /dev/null +++ b/src/storage/parsers/ParseSprite.h @@ -0,0 +1,29 @@ +/* + * ParseSprite.h + * + * Created on: Dec 1, 2016 + * Author: tibi + */ + +#ifndef STORAGE_PARSERS_PARSESPRITE_H_ +#define STORAGE_PARSERS_PARSESPRITE_H_ + +#include +#include + +namespace farmlands { +namespace storage { + + template <> + base::Frame* parse (boost::property_tree::ptree& root); + + template <> + base::SpriteState* parse (boost::property_tree::ptree& root); + + template <> + base::Sprite* parse (boost::property_tree::ptree& root); + +} +} + +#endif /* STORAGE_PARSERS_PARSESPRITE_H_ */ diff --git a/src/utils/DumpPropertyTree.cpp b/src/utils/DumpPropertyTree.cpp new file mode 100644 index 0000000..1c5d2d2 --- /dev/null +++ b/src/utils/DumpPropertyTree.cpp @@ -0,0 +1,43 @@ +/* + * S.cpp + * + * Created on: Dec 1, 2016 + * Author: tibi + */ + +#include +#include + +#include + +namespace farmlands { +namespace utils { + +void dumpPropertyTreeInternal(boost::property_tree::ptree& tree, unsigned level) +{ + for (auto child : tree) + { + for (unsigned i = 0; i < level; i++) + std::cout << " "; + + std::string data = child.second.data(); + boost::trim(data); + + std::cout<< "* " << child.first <<" = " << data << "\n"; + + dumpPropertyTreeInternal(child.second, level + 1); + } +} + +void dumpPropertyTree(boost::property_tree::ptree& tree) +{ + std::string data = tree.data(); + boost::trim(data); + + std::cout << "[root] = " << data << "\n"; + + dumpPropertyTreeInternal(tree, 1); +} + +} /* namespace utils */ +} /* namespace farmlands */ diff --git a/src/utils/DumpPropertyTree.h b/src/utils/DumpPropertyTree.h new file mode 100644 index 0000000..d2ba8c7 --- /dev/null +++ b/src/utils/DumpPropertyTree.h @@ -0,0 +1,21 @@ +/* + * S.h + * + * Created on: Dec 1, 2016 + * Author: tibi + */ + +#ifndef UTILS_DUMPPROPERTYTREE_H_ +#define UTILS_DUMPPROPERTYTREE_H_ + +#include + +namespace farmlands { +namespace utils { + + void dumpPropertyTree(boost::property_tree::ptree& tree); + +} /* namespace utils */ +} /* namespace farmlands */ + +#endif /* UTILS_DUMPPROPERTYTREE_H_ */ diff --git a/src/utils/Exceptions.cpp b/src/utils/Exceptions.cpp index eb7ef47..c24252f 100644 --- a/src/utils/Exceptions.cpp +++ b/src/utils/Exceptions.cpp @@ -36,7 +36,9 @@ Exception::~Exception() } -DEFINE_EXCEPTION_CPP(InvalidArgumentException, Exception) +DEFINE_EXCEPTION_CPP(InvalidArgumentException, Exception); +DEFINE_EXCEPTION_CPP(NotImplementedException, Exception); + DEFINE_EXCEPTION_CPP(IOException, Exception); DEFINE_EXCEPTION_CPP(ResourceLoadException, IOException); diff --git a/src/utils/Exceptions.h b/src/utils/Exceptions.h index 16a6ae7..c57f612 100644 --- a/src/utils/Exceptions.h +++ b/src/utils/Exceptions.h @@ -65,8 +65,10 @@ namespace utils { // Common exceptions - DEFINE_EXCEPTION_CLASS(InvalidArgumentException, Exception); + DEFINE_EXCEPTION_CLASS(NotImplementedException, Exception); + + // IO Exceptions DEFINE_EXCEPTION_CLASS(IOException, Exception); DEFINE_EXCEPTION_CLASS(ResourceLoadException, IOException);