From ed2711d42a7815657bf0653c25b8b9be8b7f1368 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Fri, 17 Nov 2017 16:06:14 +0100 Subject: [PATCH] read (basic) tile information from file --- assets | 2 +- src/app/Assets.hpp | 8 ++++- src/app/app.cpp | 70 +++++++++++++++++++++++++----------- src/io/TokenStreamReader.hpp | 8 +++++ src/io/token.cpp | 56 +++++++++++++++++++++++++++++ src/world/Set.hpp | 2 ++ 6 files changed, 124 insertions(+), 22 deletions(-) diff --git a/assets b/assets index d3823a8..f20dde2 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit d3823a8bfe773100bbbc3dce0622ef3950559d6f +Subproject commit f20dde223f2424ca8c7d33702ebe03684b3fc673 diff --git a/src/app/Assets.hpp b/src/app/Assets.hpp index 05a45ac..68606cb 100644 --- a/src/app/Assets.hpp +++ b/src/app/Assets.hpp @@ -13,13 +13,17 @@ namespace blobs { +namespace io { + class TokenStreamReader; +} namespace app { struct Assets { std::string path; - std::string tile_path; + std::string data_path; std::string skin_path; + std::string tile_path; struct { world::Set resources; @@ -46,6 +50,8 @@ struct Assets { Assets(Assets &&) = delete; Assets &operator =(Assets &&) = delete; + void ReadTileTypes(io::TokenStreamReader &); + void LoadTileTexture(const std::string &name, graphics::ArrayTexture &, int layer) const; void LoadSkinTexture(const std::string &name, graphics::ArrayTexture &, int layer) const; diff --git a/src/app/app.cpp b/src/app/app.cpp index cfdbf80..a67d1a8 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -4,10 +4,15 @@ #include "init.hpp" #include "../graphics/Viewport.hpp" +#include "../io/Token.hpp" +#include "../io/TokenStreamReader.hpp" +#include #include #include +using std::string; + namespace blobs { namespace app { @@ -167,8 +172,9 @@ void State::OnQuit() { Assets::Assets() : path("assets/") -, tile_path(path + "tiles/") -, skin_path(path + "skins/") { +, data_path(path + "data/") +, skin_path(path + "skins/") +, tile_path(path + "tiles/") { data.resources.Add({ "air", "Air", 0 }); data.resources.Add({ "biomass", "Biomass", 0 }); data.resources.Add({ "dirt", "Dirt", 0 }); @@ -178,20 +184,11 @@ Assets::Assets() data.resources.Add({ "water", "Water", 0 }); data.resources.Add({ "wood", "Wood", 0 }); - data.tiles.Add({ "algae", "Algae", 0, 0 }); - data.tiles.Add({ "desert", "Desert", 0, 1 }); - data.tiles.Add({ "forest", "Forest", 0, 2 }); - data.tiles.Add({ "grass", "Grass", 0, 3 }); - data.tiles.Add({ "ice", "Ice", 0, 4 }); - data.tiles.Add({ "jungle", "Jungle", 0, 5 }); - data.tiles.Add({ "mountain", "Mountain", 0, 6 }); - data.tiles.Add({ "ocean", "Ocean", 0, 7 }); - data.tiles.Add({ "rock", "Rock", 0, 8 }); - data.tiles.Add({ "sand", "Sand", 0, 9 }); - data.tiles.Add({ "taiga", "Taiga", 0, 10 }); - data.tiles.Add({ "tundra", "Tundra", 0, 11 }); - data.tiles.Add({ "water", "Water", 0, 12 }); - data.tiles.Add({ "wheat", "Wheat", 0, 13 }); + { + std::ifstream tile_file(data_path + "tiles"); + io::TokenStreamReader tile_reader(tile_file); + ReadTileTypes(tile_reader); + } data.tiles["algae"] .resources.push_back({ data.resources["water"].id, 1.0 }); data.tiles["algae"] .resources.push_back({ data.resources["biomass"].id, 0.5 }); @@ -252,8 +249,41 @@ Assets::Assets() Assets::~Assets() { } -void Assets::LoadTileTexture(const std::string &name, graphics::ArrayTexture &tex, int layer) const { - std::string path = tile_path + name + ".png"; +void Assets::ReadTileTypes(io::TokenStreamReader &in) { + while (in.HasMore()) { + string name; + in.ReadIdentifier(name); + in.Skip(io::Token::EQUALS); + + int id = 0; + if (data.tiles.Has(name)) { + id = data.tiles[name].id; + } else { + world::TileType type; + type.name = name; + id = data.tiles.Add(type); + } + + in.Skip(io::Token::ANGLE_BRACKET_OPEN); + while (in.Peek().type != io::Token::ANGLE_BRACKET_CLOSE) { + in.ReadIdentifier(name); + in.Skip(io::Token::EQUALS); + if (name == "label") { + in.ReadString(data.tiles[id].label); + } else if (name == "texture") { + data.tiles[id].texture = in.GetInt(); + } else { + throw std::runtime_error("unknown tile type property '" + name + "'"); + } + in.Skip(io::Token::SEMICOLON); + } + in.Skip(io::Token::ANGLE_BRACKET_CLOSE); + in.Skip(io::Token::SEMICOLON); + } +} + +void Assets::LoadTileTexture(const string &name, graphics::ArrayTexture &tex, int layer) const { + string path = tile_path + name + ".png"; SDL_Surface *srf = IMG_Load(path.c_str()); if (!srf) { throw SDLError("IMG_Load"); @@ -267,8 +297,8 @@ void Assets::LoadTileTexture(const std::string &name, graphics::ArrayTexture &te SDL_FreeSurface(srf); } -void Assets::LoadSkinTexture(const std::string &name, graphics::ArrayTexture &tex, int layer) const { - std::string path = skin_path + name + ".png"; +void Assets::LoadSkinTexture(const string &name, graphics::ArrayTexture &tex, int layer) const { + string path = skin_path + name + ".png"; SDL_Surface *srf = IMG_Load(path.c_str()); if (!srf) { throw SDLError("IMG_Load"); diff --git a/src/io/TokenStreamReader.hpp b/src/io/TokenStreamReader.hpp index e2945c4..8aa2d8b 100644 --- a/src/io/TokenStreamReader.hpp +++ b/src/io/TokenStreamReader.hpp @@ -25,6 +25,7 @@ public: void ReadBoolean(bool &); void ReadIdentifier(std::string &); + void ReadNumber(double &); void ReadNumber(float &); void ReadNumber(int &); void ReadNumber(unsigned long &); @@ -34,11 +35,16 @@ public: void ReadVec(glm::vec3 &); void ReadVec(glm::vec4 &); + void ReadVec(glm::dvec2 &); + void ReadVec(glm::dvec3 &); + void ReadVec(glm::dvec4 &); + void ReadVec(glm::ivec2 &); void ReadVec(glm::ivec3 &); void ReadVec(glm::ivec4 &); void ReadQuat(glm::quat &); + void ReadQuat(glm::dquat &); // the Get* functions advance to the next token // the As* functions try to cast the current token @@ -46,6 +52,8 @@ public: bool GetBool(); bool AsBool() const; + float GetDouble(); + float AsDouble() const; float GetFloat(); float AsFloat() const; int GetInt(); diff --git a/src/io/token.cpp b/src/io/token.cpp index c15d65a..4e7483f 100644 --- a/src/io/token.cpp +++ b/src/io/token.cpp @@ -319,6 +319,10 @@ void TokenStreamReader::ReadIdentifier(string &out) { out = GetValue(); } +void TokenStreamReader::ReadNumber(double &n) { + n = GetDouble(); +} + void TokenStreamReader::ReadNumber(float &n) { n = GetFloat(); } @@ -368,6 +372,36 @@ void TokenStreamReader::ReadVec(glm::vec4 &v) { Skip(Token::BRACKET_CLOSE); } +void TokenStreamReader::ReadVec(glm::dvec2 &v) { + Skip(Token::BRACKET_OPEN); + ReadNumber(v.x); + Skip(Token::COMMA); + ReadNumber(v.y); + Skip(Token::BRACKET_CLOSE); +} + +void TokenStreamReader::ReadVec(glm::dvec3 &v) { + Skip(Token::BRACKET_OPEN); + ReadNumber(v.x); + Skip(Token::COMMA); + ReadNumber(v.y); + Skip(Token::COMMA); + ReadNumber(v.z); + Skip(Token::BRACKET_CLOSE); +} + +void TokenStreamReader::ReadVec(glm::dvec4 &v) { + Skip(Token::BRACKET_OPEN); + ReadNumber(v.x); + Skip(Token::COMMA); + ReadNumber(v.y); + Skip(Token::COMMA); + ReadNumber(v.z); + Skip(Token::COMMA); + ReadNumber(v.w); + Skip(Token::BRACKET_CLOSE); +} + void TokenStreamReader::ReadVec(glm::ivec2 &v) { Skip(Token::BRACKET_OPEN); ReadNumber(v.x); @@ -410,6 +444,18 @@ void TokenStreamReader::ReadQuat(glm::quat &q) { Skip(Token::BRACKET_CLOSE); } +void TokenStreamReader::ReadQuat(glm::dquat &q) { + Skip(Token::BRACKET_OPEN); + ReadNumber(q.w); + Skip(Token::COMMA); + ReadNumber(q.x); + Skip(Token::COMMA); + ReadNumber(q.y); + Skip(Token::COMMA); + ReadNumber(q.z); + Skip(Token::BRACKET_CLOSE); +} + bool TokenStreamReader::GetBool() { Next(); @@ -438,6 +484,16 @@ bool TokenStreamReader::AsBool() const { } } +float TokenStreamReader::GetDouble() { + Next(); + return AsDouble(); +} + +float TokenStreamReader::AsDouble() const { + Assert(Token::NUMBER); + return stod(GetValue()); +} + float TokenStreamReader::GetFloat() { Next(); return AsFloat(); diff --git a/src/world/Set.hpp b/src/world/Set.hpp index c4aa6e9..af4d8a2 100644 --- a/src/world/Set.hpp +++ b/src/world/Set.hpp @@ -22,6 +22,8 @@ public: types.back().id = id; return id; } + bool Has(int id) const noexcept { return id < types.size(); } + bool Has(const std::string &name) const noexcept { return names.find(name) != names.end(); } Type &operator [](int id) noexcept { return types[id]; } const Type &operator [](int id) const noexcept { return types[id]; } -- 2.39.2