// 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 #include #include #include #include #include #include GameFunctionTable g_gameFunctions{}; namespace ia::iae { SDL_Window *g_windowHandle; VOID __Internal_Engine::Initialize() { IAE_LOG_INFO("Booting IAEngine for ", g_gameFunctions.GetName()); if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_GAMEPAD)) THROW_UNKNOWN("Failed to intialize SDL: ", SDL_GetError()); if (!(g_windowHandle = SDL_CreateWindow(g_gameFunctions.GetName(), 800, 600, SDL_WINDOW_RESIZABLE))) THROW_UNKNOWN("Failed to create the SDL window: ", SDL_GetError()); SDL_SetWindowResizable(g_windowHandle, false); const auto gameVersion = g_gameFunctions.GetVersion(); SDL_SetAppMetadata(g_gameFunctions.GetName(), BuildString(gameVersion).c_str(), g_gameFunctions.GetPackageName()); Time::Initialize(); Random::Initialize(); Renderer::Initialize(); AudioManager::Initialize(); EventManager::Initialize(); InputManager::Initialize(); ResourceManager::Initialize(); WorldManager::Initialize(); g_gameFunctions.OnInitialize(); } VOID __Internal_Engine::Terminate() { g_gameFunctions.OnTerminate(); WorldManager::Terminate(); ResourceManager::Terminate(); InputManager::Terminate(); EventManager::Terminate(); AudioManager::Terminate(); Renderer::Terminate(); Random::Terminate(); Time::Terminate(); SDL_DestroyWindow(g_windowHandle); IAE_LOG_INFO("Shutting down IAEngine"); } VOID __Internal_Engine::Iterate() { WorldManager::Update(); Renderer::BeginFrame(); WorldManager::Draw(); Renderer::EndFrame(); } VOID __Internal_Engine::ProcessEvent(IN SDL_Event *event) { switch (event->type) { case SDL_EVENT_WINDOW_RESIZED: Engine::ResizeDisplay(event->window.data1, event->window.data2); break; } InputManager::OnSDLEvent(event); EventManager::OnSDLEvent(event); ImGui_ImplSDL3_ProcessEvent(event); } } // namespace ia::iae BOOL ValidateGameFunctionTable(IN GameFunctionTable gameFunctionTable) { if (!gameFunctionTable.OnInitialize) return false; if (!gameFunctionTable.OnTerminate) return false; if (!gameFunctionTable.OnDebugDraw) return false; if (!gameFunctionTable.OnFixedUpdate) return false; if (!gameFunctionTable.OnUpdate) return false; if (!gameFunctionTable.OnResize) return false; if (!gameFunctionTable.GetName) return false; if (!gameFunctionTable.GetVersion) return false; if (!gameFunctionTable.GetPackageName) return false; if (!gameFunctionTable.GetDeveloperName) return false; if (!gameFunctionTable.GetPublisherName) return false; return true; } C_DECL(IAE_DLL_API INT32 IAEngine_Run(IN GameFunctionTable gameFunctionTable)) { if (!ValidateGameFunctionTable(gameFunctionTable)) { IAE_LOG_ERROR("Invalid game function table was passed to the engine. Exiting.."); return -1; } g_gameFunctions = gameFunctionTable; __Internal_Engine::Initialize(); SDL_Event event{}; while(true) { SDL_PollEvent(&event); if (event.type == SDL_EVENT_QUIT) break; __Internal_Engine::ProcessEvent(&event); __Internal_Engine::Iterate(); } __Internal_Engine::Terminate(); return 0; }