diff --git a/assets/manifest.xml b/assets/manifest.xml index d7360d3..cd7cf09 100644 --- a/assets/manifest.xml +++ b/assets/manifest.xml @@ -1,14 +1,19 @@ + + + + - - - + - + + - - + - + + + + diff --git a/meson.build b/meson.build index 8cf4790..bb69ecb 100644 --- a/meson.build +++ b/meson.build @@ -28,6 +28,7 @@ executable( 'src/Services.cpp', 'src/Service.cpp', 'src/Sprite.cpp', + 'src/Manifest.cpp', # Logs 'src/logs/Logs.cpp', @@ -45,6 +46,9 @@ executable( 'src/gfx/Texture.cpp', 'src/gfx/Shape.cpp', + # Inputs + 'src/inputs/Inputs.cpp', + # Resources 'src/res/Resources.cpp', 'src/res/BaseRes.cpp', diff --git a/src/Game.cpp b/src/Game.cpp index 6247135..474fa04 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -3,6 +3,8 @@ #include "events/Events.hpp" #include "logs/Logs.hpp" #include "gfx/Graphics.hpp" +#include "inputs/Inputs.hpp" + #include "Sprite.hpp" namespace ml @@ -36,6 +38,11 @@ namespace ml } } + if (ML_SYS(Inputs)->is_action_just_pressed("hello")) + { + ML_SYS(FileLogs)->log(LEVEL_DEBUG, "hello triggered"); + } + ML_SYS(Graphics)->clear(4, 139, 154); ML_SYS(Graphics)->draw(sprite); ML_SYS(Graphics)->update(); diff --git a/src/Manifest.cpp b/src/Manifest.cpp new file mode 100644 index 0000000..60677c9 --- /dev/null +++ b/src/Manifest.cpp @@ -0,0 +1,71 @@ +#include "Manifest.hpp" +#include "ml.hpp" + +namespace ml +{ + /*explicit*/ Manifest::Manifest() + { + } + + /*virtual*/ Manifest::~Manifest() + { + } + + void Manifest::load() + { + xml::XMLDocument doc; + doc.LoadFile(ML_ASSET("manifest.xml").c_str()); + auto root = doc.RootElement(); + + resources(root->FirstChildElement("resources")); + actions(root->FirstChildElement("actions")); + } + + void Manifest::resources(xml::XMLElement* resources) + { + xml::XMLElement* itr = resources->FirstChildElement(); + + while (itr) + { + std::string type = itr->Attribute("type"); + std::filesystem::path path = itr->Attribute("path"); + std::string name = itr->Attribute("name"); + + if (type == "text") + { + ML_SYS(Resources)->load(name, path); + } + else if (type == "image") + { + ML_SYS(Resources)->load(name, path); + } + else + { + throw resource_error {"unknown resource '" + + name + + "' of type '" + type + "'"}; + } + + itr = itr->NextSiblingElement(); + } + } + + void Manifest::actions(xml::XMLElement* actions) + { + auto itr = actions->FirstChildElement(); + + while (itr) + { + std::string name = itr->Attribute("name"); + + if (auto key = itr->Attribute("key", nullptr); + key) + { + SDL_Keycode code = SDL_GetKeyFromName(key); + ML_SYS(Inputs)->bind(std::string(name), code); + } + + itr = itr->NextSiblingElement(); + } + } +} diff --git a/src/Manifest.hpp b/src/Manifest.hpp new file mode 100644 index 0000000..63d6184 --- /dev/null +++ b/src/Manifest.hpp @@ -0,0 +1,28 @@ +#ifndef ml_MANIFEST_HPP +#define ml_MANIFEST_HPP + +#include +#include "commons.hpp" + +namespace xml = tinyxml2; + +namespace ml +{ + /** + * Main game configuration file. + **/ + class Manifest + { + public: + explicit Manifest(); + virtual ~Manifest(); + + void load(); + + private: + void resources(xml::XMLElement* resources); + void actions(xml::XMLElement* actions); + }; +} + +#endif diff --git a/src/inputs/Inputs.cpp b/src/inputs/Inputs.cpp new file mode 100644 index 0000000..80ce32c --- /dev/null +++ b/src/inputs/Inputs.cpp @@ -0,0 +1,60 @@ +#include "Inputs.hpp" +#include "SDL_keycode.h" + +namespace ml +{ + /*explicit*/ Inputs::Inputs() + { + } + + /*virtual*/ Inputs::~Inputs() + { + } + + void Inputs::bind(std::string const& action, SDL_Keycode code) + { + if (auto itr=m_actions.find(action); + itr != std::end(m_actions)) + { + itr->second.push_back(code); + } + else + { + m_actions.insert({action, {code}}); + } + } + + bool Inputs::is_action_pressed(std::string const& action) + { + int len = 0; + Uint8 const* keys = SDL_GetKeyboardState(&len); + + if (auto itr = m_actions.find(action); + itr != std::end(m_actions)) + { + for (SDL_Keycode key: itr->second) + { + if (keys[SDL_GetScancodeFromKey(key)]) + { + return true; + } + } + } + + return false; + } + + bool Inputs::is_action_just_pressed(std::string const& action) + { + static bool prev = false; + bool pressed = is_action_pressed(action); + + if (pressed != prev) + { + prev = pressed; + return pressed; + } + + return false; + } +} diff --git a/src/inputs/Inputs.hpp b/src/inputs/Inputs.hpp new file mode 100644 index 0000000..ee34195 --- /dev/null +++ b/src/inputs/Inputs.hpp @@ -0,0 +1,27 @@ +#ifndef ml_INPUTS_HPP +#define ml_INPUTS_HPP + +#include +#include "../commons.hpp" +#include "../Service.hpp" + +namespace ml +{ + class Inputs: public Service + { + public: + explicit Inputs(); + virtual ~Inputs(); + + void bind(std::string const& action, SDL_Keycode code); + + bool is_action_pressed(std::string const& action); + bool is_action_just_pressed(std::string const& action); + + private: + std::unordered_map> + m_actions; + }; +} + +#endif diff --git a/src/logs/Logs.cpp b/src/logs/Logs.cpp index 3353bdc..4f163df 100644 --- a/src/logs/Logs.cpp +++ b/src/logs/Logs.cpp @@ -36,6 +36,6 @@ namespace ml << time_str << " " << ("\033[" + color + "m[" + level_str + "]\033[0m ") << message - << "\n"; + << std::endl; } } diff --git a/src/main.cpp b/src/main.cpp index 8b1f7d4..74c9e8e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -9,8 +9,9 @@ #include "events/Events.hpp" #include "gfx/Graphics.hpp" #include "res/Resources.hpp" +#include "inputs/Inputs.hpp" - +#include "Manifest.hpp" #include "Game.hpp" int main(int, char**) @@ -22,8 +23,12 @@ int main(int, char**) ML->add(); ML->add("Mornelune", 1024, 768); + ML->add(); ML->init(); + ml::Manifest man; + man.load(); + ml::Game game; game.start(); game.stop(); diff --git a/src/ml.hpp b/src/ml.hpp new file mode 100644 index 0000000..62d8c1b --- /dev/null +++ b/src/ml.hpp @@ -0,0 +1,9 @@ +#ifndef ml_ML_HPP +#define ml_ML_HPP + +#include "res/Resources.hpp" +#include "inputs/Inputs.hpp" +#include "gfx/Graphics.hpp" +#include "events/Events.hpp" + +#endif diff --git a/src/res/Resources.cpp b/src/res/Resources.cpp index 417fd96..a9b93a0 100644 --- a/src/res/Resources.cpp +++ b/src/res/Resources.cpp @@ -16,38 +16,4 @@ namespace ml /*virtual*/ Resources::~Resources() { } - - void Resources::init() /*override*/ - { - xml::XMLDocument doc; - doc.LoadFile(ML_ASSET("manifest.xml").string().c_str()); - - auto* root = doc.RootElement(); - - xml::XMLElement* itr = root->FirstChildElement(); - - while (itr) - { - std::string type = itr->Attribute("type"); - std::filesystem::path path = itr->Attribute("path"); - std::string name = itr->Attribute("name"); - - if (type == "text") - { - ML_SYS(Resources)->load(name, path); - } - else if (type == "image") - { - ML_SYS(Resources)->load(name, path); - } - else - { - throw resource_error {"unknown resource '" - + name - + "' of type '" + type + "'"}; - } - - itr = itr->NextSiblingElement(); - } - } } diff --git a/src/res/Resources.hpp b/src/res/Resources.hpp index dff9e3d..edc0934 100644 --- a/src/res/Resources.hpp +++ b/src/res/Resources.hpp @@ -3,7 +3,8 @@ #include "../commons.hpp" #include "../Service.hpp" -#include "BaseRes.hpp" +#include "TextRes.hpp" +#include "ImageRes.hpp" #include namespace ml @@ -14,8 +15,6 @@ namespace ml explicit Resources(); virtual ~Resources(); - void init() override; - template void load(std::string const& name, std::filesystem::path const& path);