X-Git-Url: https://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fapp%2Fapp.cpp;h=0ec22b02c16607d189cda86107140d14ccde643f;hb=ab817024b3c02a54a376fa8f60b5046e51128ebb;hp=064786fb82baf42403588ec4f789c23b3e1f6d2e;hpb=be413456f57da06e918ae7bf4c4f35e5198ff7ce;p=blobs.git diff --git a/src/app/app.cpp b/src/app/app.cpp index 064786f..0ec22b0 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -4,8 +4,14 @@ #include "init.hpp" #include "../graphics/Viewport.hpp" +#include "../io/Token.hpp" +#include "../io/TokenStreamReader.hpp" +#include #include +#include + +using std::string; namespace blobs { @@ -164,22 +170,195 @@ void State::OnQuit() { } -Assets::Assets() { +Assets::Assets() +: path("assets/") +, data_path(path + "data/") +, font_path(path + "fonts/") +, skin_path(path + "skins/") +, tile_path(path + "tiles/") +, fonts{ + graphics::Font(font_path + "DejaVuSans.ttf", 32), + graphics::Font(font_path + "DejaVuSans.ttf", 24), + graphics::Font(font_path + "DejaVuSans.ttf", 16) +} { + { + std::ifstream resource_file(data_path + "resources"); + io::TokenStreamReader resource_reader(resource_file); + ReadResources(resource_reader); + } + + { + std::ifstream tile_file(data_path + "tiles"); + io::TokenStreamReader tile_reader(tile_file); + ReadTileTypes(tile_reader); + } + + graphics::Format format; textures.tiles.Bind(); - textures.tiles.Reserve(1, 1, 3, format); - std::uint8_t texdata[] = { - 0xFF, 0x00, 0x00, 0xFF, - 0x00, 0xFF, 0x00, 0xFF, - 0x00, 0x00, 0xFF, 0xFF, - }; - textures.tiles.Data(0, format, texdata); - textures.tiles.Data(1, format, texdata + 4); - textures.tiles.Data(2, format, texdata + 8); + textures.tiles.Reserve(256, 256, 14, format); + LoadTileTexture("algae", textures.tiles, 0); + LoadTileTexture("desert", textures.tiles, 1); + LoadTileTexture("forest", textures.tiles, 2); + LoadTileTexture("grass", textures.tiles, 3); + LoadTileTexture("ice", textures.tiles, 4); + LoadTileTexture("jungle", textures.tiles, 5); + LoadTileTexture("mountain", textures.tiles, 6); + LoadTileTexture("ocean", textures.tiles, 7); + LoadTileTexture("rock", textures.tiles, 8); + LoadTileTexture("sand", textures.tiles, 9); + LoadTileTexture("taiga", textures.tiles, 10); + LoadTileTexture("tundra", textures.tiles, 11); + LoadTileTexture("water", textures.tiles, 12); + LoadTileTexture("wheat", textures.tiles, 13); + + textures.skins.Bind(); + textures.skins.Reserve(256, 256, 9, format); + LoadSkinTexture("1", textures.skins, 0); + LoadSkinTexture("2", textures.skins, 1); + LoadSkinTexture("3", textures.skins, 2); + LoadSkinTexture("4", textures.skins, 3); + LoadSkinTexture("5", textures.skins, 4); + LoadSkinTexture("6", textures.skins, 5); + LoadSkinTexture("7", textures.skins, 6); + LoadSkinTexture("8", textures.skins, 7); + LoadSkinTexture("9", textures.skins, 8); } Assets::~Assets() { } +void Assets::ReadResources(io::TokenStreamReader &in) { + while (in.HasMore()) { + string name; + in.ReadIdentifier(name); + in.Skip(io::Token::EQUALS); + + int id = 0; + if (data.resources.Has(name)) { + id = data.resources[name].id; + } else { + world::Resource res; + res.name = name; + id = data.resources.Add(res); + } + + 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.resources[id].label); + } else if (name == "state") { + in.ReadIdentifier(name); + if (name == "solid") { + data.resources[id].state = world::Resource::SOLID; + } else if (name == "liquid") { + data.resources[id].state = world::Resource::LIQUID; + } else if (name == "gas") { + data.resources[id].state = world::Resource::GAS; + } else if (name == "plasma") { + data.resources[id].state = world::Resource::PLASMA; + } else { + throw std::runtime_error("unknown resource state '" + name + "'"); + } + } else { + throw std::runtime_error("unknown resource property '" + name + "'"); + } + in.Skip(io::Token::SEMICOLON); + } + in.Skip(io::Token::ANGLE_BRACKET_CLOSE); + in.Skip(io::Token::SEMICOLON); + } +} + +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 if (name == "yield") { + in.Skip(io::Token::BRACKET_OPEN); + while (in.Peek().type != io::Token::BRACKET_CLOSE) { + world::TileType::Yield yield; + 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 == "resource") { + in.ReadIdentifier(name); + yield.resource = data.resources[name].id; + } else if (name == "ubiquity") { + yield.ubiquity = in.GetDouble(); + } else { + throw std::runtime_error("unknown tile type yield property '" + name + "'"); + } + in.Skip(io::Token::SEMICOLON); + } + in.Skip(io::Token::ANGLE_BRACKET_CLOSE); + data.tiles[id].resources.push_back(yield); + if (in.Peek().type == io::Token::COMMA) { + in.Skip(io::Token::COMMA); + } + } + in.Skip(io::Token::BRACKET_CLOSE); + } 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"); + } + try { + tex.Data(layer, *srf); + } catch (...) { + SDL_FreeSurface(srf); + throw; + } + SDL_FreeSurface(srf); +} + +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"); + } + try { + tex.Data(layer, *srf); + } catch (...) { + SDL_FreeSurface(srf); + throw; + } + SDL_FreeSurface(srf); +} + } }