// IAEngine: 2D Game Engine by IA // Copyright (C) 2025 IASoft (PVT) LTD (oss@iasoft.dev) // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include #include #include #include #include #include #include namespace ia::iae { EXTERN SDL_Window *g_windowHandle; SIZE_T g_resourceNameCounter{1}; Vec2 g_sceneScalingFactor{1.0f}; Vec2 g_sceneDesignViewport{1.0f}; BOOL Engine::IsDebugMode() { #if defined(__DEBUG_MODE__) return true; #else return false; #endif } String Engine::ReadTextAsset(IN CONST String &path) { SDL_IOStream *f = SDL_IOFromFile(path.c_str(), "r"); if (!f) THROW_FILE_OPEN_READ(path); Vector result; SDL_SeekIO(f, 0, SDL_IO_SEEK_END); result.resize(SDL_TellIO(f) + 1); SDL_SeekIO(f, 0, SDL_IO_SEEK_SET); SDL_ReadIO(f, result.data(), result.size()); result.back() = '\0'; SDL_CloseIO(f); return result.data(); } Vector Engine::ReadBinaryAsset(IN CONST String &path) { SDL_IOStream *f = SDL_IOFromFile(path.c_str(), "rb"); if (!f) THROW_FILE_OPEN_READ(path); Vector result; SDL_SeekIO(f, 0, SDL_IO_SEEK_END); result.resize(SDL_TellIO(f)); SDL_SeekIO(f, 0, SDL_IO_SEEK_SET); SDL_ReadIO(f, result.data(), result.size()); SDL_CloseIO(f); return result; } Vec2 Engine::CalculatePercentPosition(IN Vec2 percent) { return Vec2{Renderer::s_activeSceneDesignViewport.x / 100.0f, Renderer::s_activeSceneDesignViewport.y / 100.0f} * percent; } Direction Engine::GetVectorPointingDirection(IN Vec2 v) { STATIC CONSTEXPR Direction DIRECTION_MAP[] = {Direction::RIGHT, Direction::DOWN_RIGHT, Direction::DOWN, Direction::DOWN_LEFT, Direction::LEFT, Direction::UP_LEFT, Direction::UP, Direction::UP_RIGHT}; if ((abs(v.x) <= FLOAT32_EPSILON) && (abs(v.y) <= FLOAT32_EPSILON)) return Direction::NONE; auto angle = glm::degrees(atan2(v.y, v.x)); if (angle < 0) angle += 360; return DIRECTION_MAP[INT32((angle + 22.5) / 45) % 8]; } VOID Engine::ResizeDisplay(IN INT32 newWidth, IN INT32 newHeight) { Renderer::WaitForGPUIdle(); SDL_SetWindowSize(g_windowHandle, newWidth, newHeight); Renderer::OnScreenResize(newWidth, newHeight); UI::OnScreenResize(newWidth, newHeight); Game_OnResize(newWidth, newHeight); } Handle Engine::CreateImageFromFile(IN CONST String &name, IN CONST String &path, IN INT32 resizeToWidth, IN INT32 resizeToHeight) { const auto data = ReadBinaryAsset(path); const auto handle = CreateImage(name, data.data(), data.size()); if (!resizeToWidth || !resizeToHeight) return handle; const auto extent = GetImageExtent(handle); const auto newHandle = ResourceManager::RescaleImage( handle, {(FLOAT32) resizeToWidth / (FLOAT32) extent.x, (FLOAT32) resizeToHeight / (FLOAT32) extent.y}, true); return newHandle; } Handle Engine::CreateSoundFromFile(IN CONST String &name, IN CONST String &path) { const auto data = File::ReadToVector(path.c_str()); return CreateSound(name, data.data(), data.size()); } Handle Engine::CreateTileSetFromFile(IN CONST String &name, IN CONST String &path, IN INT32 tileWidth, IN INT32 tileHeight) { return CreateTileSet(name, CreateImageFromFile(name, path), tileWidth, tileHeight); } Handle Engine::RescaleImage(IN CONST String &name, IN Vec2 factor) { return ResourceManager::RescaleImage(GetImage(name), factor); } String Engine::GetUniqueResourceName() { return BuildString("__res_", g_resourceNameCounter++); } Vec2 Engine::GetSceneScalingFactor() { return g_sceneScalingFactor; } } // namespace ia::iae