X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fapp%2Fapp.cpp;h=0f50aa75d00104a21fe5a32a988bef297a98580f;hb=ea55fc457b7d0068225af447da4a5c5489ccd239;hp=a67d1a8286527d582de03627a7bbef6516c2f828;hpb=ed2711d42a7815657bf0653c25b8b9be8b7f1368;p=blobs.git diff --git a/src/app/app.cpp b/src/app/app.cpp index a67d1a8..0f50aa7 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -173,47 +173,28 @@ void State::OnQuit() { Assets::Assets() : path("assets/") , data_path(path + "data/") +, font_path(path + "fonts/") , 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 }); - data.resources.Add({ "ice", "Ice", 0 }); - data.resources.Add({ "rock", "Rock", 0 }); - data.resources.Add({ "sand", "Sand", 0 }); - data.resources.Add({ "water", "Water", 0 }); - data.resources.Add({ "wood", "Wood", 0 }); +, sky_path(path + "skies/") +, tile_path(path + "tiles/") +, random(0x6283B64CEFE57925) +, 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"); + std::ifstream tile_file(data_path + "tile_types"); 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 }); - data.tiles["desert"] .resources.push_back({ data.resources["sand"].id, 1.0 }); - data.tiles["forest"] .resources.push_back({ data.resources["wood"].id, 1.0 }); - data.tiles["forest"] .resources.push_back({ data.resources["dirt"].id, 0.5 }); - data.tiles["grass"] .resources.push_back({ data.resources["dirt"].id, 0.5 }); - data.tiles["grass"] .resources.push_back({ data.resources["biomass"].id, 0.25 }); - data.tiles["grass"] .resources.push_back({ data.resources["water"].id, 0.25 }); - data.tiles["ice"] .resources.push_back({ data.resources["ice"].id, 1.0 }); - data.tiles["ice"] .resources.push_back({ data.resources["water"].id, 0.25 }); - data.tiles["jungle"] .resources.push_back({ data.resources["wood"].id, 0.5 }); - data.tiles["jungle"] .resources.push_back({ data.resources["biomass"].id, 0.5 }); - data.tiles["mountain"].resources.push_back({ data.resources["rock"].id, 1.0 }); - data.tiles["ocean"] .resources.push_back({ data.resources["water"].id, 1.0 }); - data.tiles["rock"] .resources.push_back({ data.resources["rock"].id, 1.0 }); - data.tiles["sand"] .resources.push_back({ data.resources["sand"].id, 1.0 }); - data.tiles["taiga"] .resources.push_back({ data.resources["wood"].id, 1.0 }); - data.tiles["taiga"] .resources.push_back({ data.resources["water"].id, 0.5 }); - data.tiles["tundra"] .resources.push_back({ data.resources["rock"].id, 1.0 }); - data.tiles["tundra"] .resources.push_back({ data.resources["ice"].id, 0.5 }); - data.tiles["water"] .resources.push_back({ data.resources["water"].id, 1.0 }); - data.tiles["water"] .resources.push_back({ data.resources["biomass"].id, 0.25 }); - data.tiles["wheat"] .resources.push_back({ data.resources["biomass"].id, 1.0 }); - data.tiles["wheat"] .resources.push_back({ data.resources["water"].id, 0.25 }); graphics::Format format; textures.tiles.Bind(); @@ -232,23 +213,96 @@ Assets::Assets() LoadTileTexture("tundra", textures.tiles, 11); LoadTileTexture("water", textures.tiles, 12); LoadTileTexture("wheat", textures.tiles, 13); + textures.tiles.FilterTrilinear(); 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); + LoadSkinTexture("plain", textures.skins, 0); + LoadSkinTexture("stripes", textures.skins, 1); + LoadSkinTexture("dots", textures.skins, 2); + LoadSkinTexture("lines", textures.skins, 3); + LoadSkinTexture("spots", textures.skins, 4); + LoadSkinTexture("circles", textures.skins, 5); + textures.skins.FilterTrilinear(); + + textures.sky.Bind(); + LoadSkyTexture("blue", textures.sky); + textures.sky.FilterTrilinear(); + textures.sky.WrapEdge(); } 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 == "density") { + data.resources[id].density = in.GetDouble(); + } else if (name == "energy") { + data.resources[id].energy = in.GetDouble(); + data.resources[id].inverse_energy = 1.0 / data.resources[id].energy; + } 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 if (name == "base_color") { + in.ReadVec(data.resources[id].base_color); + } else if (name == "compatibility") { + in.Skip(io::Token::ANGLE_BRACKET_OPEN); + while (in.Peek().type != io::Token::ANGLE_BRACKET_CLOSE) { + in.ReadIdentifier(name); + int sub_id = 0; + if (data.resources.Has(name)) { + sub_id = data.resources[name].id; + } else { + world::Resource res; + res.name = name; + sub_id = data.resources.Add(res); + } + in.Skip(io::Token::COLON); + double value = in.GetDouble(); + in.Skip(io::Token::SEMICOLON); + data.resources[id].compatibility[sub_id] = value; + } + in.Skip(io::Token::ANGLE_BRACKET_CLOSE); + } 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; @@ -256,12 +310,12 @@ void Assets::ReadTileTypes(io::TokenStreamReader &in) { in.Skip(io::Token::EQUALS); int id = 0; - if (data.tiles.Has(name)) { - id = data.tiles[name].id; + if (data.tile_types.Has(name)) { + id = data.tile_types[name].id; } else { world::TileType type; type.name = name; - id = data.tiles.Add(type); + id = data.tile_types.Add(type); } in.Skip(io::Token::ANGLE_BRACKET_OPEN); @@ -269,9 +323,34 @@ void Assets::ReadTileTypes(io::TokenStreamReader &in) { in.ReadIdentifier(name); in.Skip(io::Token::EQUALS); if (name == "label") { - in.ReadString(data.tiles[id].label); + in.ReadString(data.tile_types[id].label); } else if (name == "texture") { - data.tiles[id].texture = in.GetInt(); + data.tile_types[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.tile_types[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 + "'"); } @@ -312,5 +391,71 @@ void Assets::LoadSkinTexture(const string &name, graphics::ArrayTexture &tex, in SDL_FreeSurface(srf); } +void Assets::LoadSkyTexture(const string &name, graphics::CubeMap &cm) const { + string full = sky_path + name; + string right = full + "-right.png"; + string left = full + "-left.png"; + string top = full + "-top.png"; + string bottom = full + "-bottom.png"; + string back = full + "-back.png"; + string front = full + "-front.png"; + + SDL_Surface *srf = nullptr; + + if (!(srf = IMG_Load(right.c_str()))) throw SDLError("IMG_Load"); + try { + cm.Data(graphics::CubeMap::RIGHT, *srf); + } catch (...) { + SDL_FreeSurface(srf); + throw; + } + SDL_FreeSurface(srf); + + if (!(srf = IMG_Load(left.c_str()))) throw SDLError("IMG_Load"); + try { + cm.Data(graphics::CubeMap::LEFT, *srf); + } catch (...) { + SDL_FreeSurface(srf); + throw; + } + SDL_FreeSurface(srf); + + if (!(srf = IMG_Load(top.c_str()))) throw SDLError("IMG_Load"); + try { + cm.Data(graphics::CubeMap::TOP, *srf); + } catch (...) { + SDL_FreeSurface(srf); + throw; + } + SDL_FreeSurface(srf); + + if (!(srf = IMG_Load(bottom.c_str()))) throw SDLError("IMG_Load"); + try { + cm.Data(graphics::CubeMap::BOTTOM, *srf); + } catch (...) { + SDL_FreeSurface(srf); + throw; + } + SDL_FreeSurface(srf); + + if (!(srf = IMG_Load(back.c_str()))) throw SDLError("IMG_Load"); + try { + cm.Data(graphics::CubeMap::BACK, *srf); + } catch (...) { + SDL_FreeSurface(srf); + throw; + } + SDL_FreeSurface(srf); + + if (!(srf = IMG_Load(front.c_str()))) throw SDLError("IMG_Load"); + try { + cm.Data(graphics::CubeMap::FRONT, *srf); + } catch (...) { + SDL_FreeSurface(srf); + throw; + } + SDL_FreeSurface(srf); +} + } }