// resource_helper.cpp // Resource helper implementation #include "resource_helper.hpp" #include #include #include #include #include "resource_loader.hpp" namespace Resource::Helper { static bool resource_system_initialized = false; // Initialize the resource system auto initializeResourceSystem(const std::string& pack_file, bool enable_fallback) -> bool { if (resource_system_initialized) { std::cout << "ResourceHelper: Already initialized\n"; return true; } std::cout << "ResourceHelper: Initializing with pack: " << pack_file << '\n'; std::cout << "ResourceHelper: Fallback enabled: " << (enable_fallback ? "Yes" : "No") << '\n'; bool success = Loader::get().initialize(pack_file, enable_fallback); if (success) { resource_system_initialized = true; std::cout << "ResourceHelper: Initialization successful\n"; } else { std::cerr << "ResourceHelper: Initialization failed\n"; } return success; } // Shutdown the resource system void shutdownResourceSystem() { if (resource_system_initialized) { Loader::get().shutdown(); resource_system_initialized = false; std::cout << "ResourceHelper: Shutdown complete\n"; } } // Load a file auto loadFile(const std::string& filepath) -> std::vector { if (!resource_system_initialized) { std::cerr << "ResourceHelper: System not initialized, loading from filesystem\n"; // Fallback to direct filesystem access std::ifstream file(filepath, std::ios::binary | std::ios::ate); if (!file) { return {}; } std::streamsize file_size = file.tellg(); file.seekg(0, std::ios::beg); std::vector data(file_size); file.read(reinterpret_cast(data.data()), file_size); return data; } // Determine if we should use the pack if (shouldUseResourcePack(filepath)) { // Convert to pack path std::string pack_path = getPackPath(filepath); // Try to load from pack auto data = Loader::get().loadResource(pack_path); if (!data.empty()) { return data; } // If pack loading failed, try filesystem as fallback std::cerr << "ResourceHelper: Pack failed for " << pack_path << ", trying filesystem\n"; } // Load from filesystem return Loader::get().loadResource(filepath); } // Check if a file exists auto fileExists(const std::string& filepath) -> bool { if (!resource_system_initialized) { return std::filesystem::exists(filepath); } // Check pack if appropriate if (shouldUseResourcePack(filepath)) { std::string pack_path = getPackPath(filepath); if (Loader::get().resourceExists(pack_path)) { return true; } } // Check filesystem return std::filesystem::exists(filepath); } // Convert asset path to pack path auto getPackPath(const std::string& asset_path) -> std::string { std::string path = asset_path; // Convert backslashes to forward slashes std::ranges::replace(path, '\\', '/'); // If it's an absolute path containing "/data/", extract everything after "/data/" // This handles paths like: /Users/sergio/.../data/palette/file.pal -> palette/file.pal size_t data_pos = path.find("/data/"); if (data_pos != std::string::npos) { return path.substr(data_pos + 6); // +6 to skip "/data/" } // Remove leading slashes while (!path.empty() && path[0] == '/') { path = path.substr(1); } // Remove "./" prefix if present if (path.starts_with("./")) { path = path.substr(2); } // Remove "../" prefixes (for macOS bundle paths in development) while (path.starts_with("../")) { path = path.substr(3); } // Remove "Resources/" prefix if present (for macOS bundle) const std::string RESOURCES_PREFIX = "Resources/"; if (path.starts_with(RESOURCES_PREFIX)) { path = path.substr(RESOURCES_PREFIX.length()); } // Remove "data/" prefix if present const std::string DATA_PREFIX = "data/"; if (path.starts_with(DATA_PREFIX)) { path = path.substr(DATA_PREFIX.length()); } return path; } // Check if file should use resource pack auto shouldUseResourcePack(const std::string& filepath) -> bool { std::string path = filepath; std::ranges::replace(path, '\\', '/'); // Don't use pack for most config files (except config/assets.yaml which is loaded // directly via Loader::loadAssetsConfig() in release builds) if (path.find("config/") != std::string::npos) { return false; } // Use pack for data files if (path.find("data/") != std::string::npos) { return true; } // Check if it looks like a data file (has common extensions) if (path.find(".ogg") != std::string::npos || path.find(".wav") != std::string::npos || path.find(".gif") != std::string::npos || path.find(".png") != std::string::npos || path.find(".pal") != std::string::npos || path.find(".yaml") != std::string::npos || path.find(".txt") != std::string::npos || path.find(".glsl") != std::string::npos) { return true; } return false; } // Check if pack is loaded auto isPackLoaded() -> bool { if (!resource_system_initialized) { return false; } return Loader::get().isPackLoaded(); } } // namespace Resource::Helper