#include "rooms.h" #include #include #include #include #include #include #include #include #include "images.h" namespace fs = std::filesystem; namespace rooms { int num_total_rooms = 0; std::string current_room = ""; std::map rooms; static const char *paletteMap[] = { "black", "bright_black", "blue", "bright_blue", "red", "bright_red", "magenta", "bright_magenta", "green", "bright_green", "cyan", "bright_cyan", "yellow", "bright_yellow", "white", "bright_white" }; const uint8_t colorToNum(std::string value) { for (int i=0; i<16; ++i) if (value == paletteMap[i]) return i; return 0; } // Trim from start (in-place) inline void ltrim(std::string& s) { s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) { return !std::isspace(ch); })); } // Trim from end (in-place) inline void rtrim(std::string& s) { s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) { return !std::isspace(ch); }).base(), s.end()); } // Trim both ends (in-place) inline void trim(std::string& s) { ltrim(s); rtrim(s); } void processKeyValue(const std::string& room_name, const std::string& section, const std::string& key, const std::string& value) { room_t& room = rooms[room_name]; if (section == "global") { if (key == "name") { room.name = value; } else if (key == "bgColor") { room.bgColor = colorToNum(value); } else if (key == "border") { room.border = colorToNum(value); //} else if (key == "tileMapFile") { // room.tileMapFile = value; } else if (key == "tileSetFile") { room.tileSetFile = images::getImage("tilesets/"+value); } else if (key == "roomUp") { room.roomUp = value; } else if (key == "roomDown") { room.roomDown = value; } else if (key == "roomLeft") { room.roomLeft = value; } else if (key == "roomRight") { room.roomRight = value; } else if (key == "itemColor1") { room.itemColor1 = colorToNum(value); } else if (key == "itemColor2") { room.itemColor2 = colorToNum(value); } } else if (section == "enemy") { if (key == "animation") { room.enemies[room.enemies.size()-1].animation = value; } else if (key == "x") { room.enemies[room.enemies.size()-1].x = std::stoi(value); } else if (key == "y") { room.enemies[room.enemies.size()-1].y = std::stoi(value); } else if (key == "vx") { room.enemies[room.enemies.size()-1].vx = std::stof(value); } else if (key == "vy") { room.enemies[room.enemies.size()-1].vy = std::stof(value); } else if (key == "x1") { room.enemies[room.enemies.size()-1].x1 = std::stoi(value); } else if (key == "y1") { room.enemies[room.enemies.size()-1].y1 = std::stoi(value); } else if (key == "x2") { room.enemies[room.enemies.size()-1].x2 = std::stoi(value); } else if (key == "y2") { room.enemies[room.enemies.size()-1].y2 = std::stoi(value); } else if (key == "color") { room.enemies[room.enemies.size()-1].color = colorToNum(value); } else if (key == "flip") { room.enemies[room.enemies.size()-1].flip = value=="true" ? true : false; } else if (key == "mirror") { room.enemies[room.enemies.size()-1].mirror = value=="true" ? true : false; } } else if (section == "item") { if (key == "tile") { room.items[room.items.size()-1].tile = std::stoi(value); } else if (key == "x") { room.items[room.items.size()-1].x = std::stoi(value); } else if (key == "y") { room.items[room.items.size()-1].y = std::stoi(value); } else if (key == "counter") { room.items[room.items.size()-1].counter = std::stof(value); } } } void loadRoom(fs::path filename) { std::string room_name = filename.stem().string(); std::ifstream file(filename); if (!file) { std::cerr << "Failed to open file.\n"; return; } std::string current_section = "global"; std::string line; while (std::getline(file, line)) { //std::cout << "'" << line << "'\n"; // Trim and clean line, ignore empty lines and comments trim(line); if (line.empty() || line[0] == '#') continue; // Remove inline comments std::size_t comment_pos = line.find('#'); if (comment_pos != std::string::npos) { line = line.substr(0, comment_pos); trim(line); } // Check if entering or exiting a section if (line[0] == '[') { std::size_t closing_pos = line.find(']'); if (closing_pos != std::string::npos && closing_pos > 1) { std::string section = line.substr(1,closing_pos-1); if (section[0] == '/') { current_section = "global"; } else { current_section = section; if (section == "enemy") rooms[room_name].enemies.emplace_back(); else if (section == "item") rooms[room_name] .items.emplace_back(); } } } // Get and process key/value std::size_t eq_pos = line.find('='); if (eq_pos != std::string::npos) { std::string key = line.substr(0, eq_pos); std::string value = line.substr(eq_pos + 1); trim(key); trim(value); processKeyValue(room_name, current_section, key, value); } } } void loadTiles(fs::path filename) { filename.replace_extension(".tmx"); std::string room_name = filename.stem().string(); std::string line; bool inData = false; int row = 0, col = 0; std::ifstream file(filename); if (!file) { std::cerr << "Failed to open file.\n"; return; } room_t& room = rooms[room_name]; while (std::getline(file, line)) { if (!inData) { if (line.find("") != std::string::npos) inData = true; continue; } if (line.find("") != std::string::npos) break; std::stringstream ss(line); std::string value; while (std::getline(ss, value, ',')) { if (!value.empty()) { room.tiles[col][row] = static_cast(std::stoi(value)); ++col; if (col == 32) { col = 0; ++row; } } } } } void load() { // Get all room files fs::path target_dir = "./data/room"; std::vector room_files; try { for (const auto& entry : fs::directory_iterator(target_dir)) { if (entry.is_regular_file() && entry.path().extension() == ".room") { room_files.push_back(entry.path()); } } std::sort(room_files.begin(), room_files.end()); for (const auto& path : room_files) { std::cout << "Processing " << path.filename() << '\n'; loadRoom(path); loadTiles(path); } } catch (const fs::filesystem_error& e) { std::cerr << "Filesystem error: " << e.what() << '\n'; } /*for (auto &item : rooms) { room_t &room = item.second; std::cout << room.name << std::endl; for (int y=0; y<16; ++y) { for (int x=0; x<32; ++x) std::cout << std::to_string(room.tiles[x][y]) << ","; std::cout << std::endl; } }*/ } }