Files
IAEngine/Src/IAEngine/imp/cpp/IAEngine.cpp
Isuru Samarathunga 67cb23d589 Fixes
2025-11-10 09:49:22 +05:30

279 lines
8.0 KiB
C++

// 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 <https://www.gnu.org/licenses/>.
// #include <EmbeddedResources.hpp>
#include <GameData.hpp>
#include <IAEngine/LibInterface.hpp>
#include <RenderCore/RenderCore.hpp>
namespace ia::iae
{
Asset_Scene *g_activeScene{};
String g_gameName;
String g_gamePackageName;
String g_gameDeveloperName;
String g_gamePublisherName;
IA_VERSION_TYPE g_gameVersion{};
Vec2 g_designViewport;
SDL_Window *g_windowHandle{};
Vector<Asset_Plugin *> g_plugins;
AssetManager* g_assetManager{};
AssetManager* g_defaultAssetManager{};
#if defined(__IA_DEBUG) && __IA_DEBUG
BOOL g_isDebugMode = true;
#else
BOOL g_isDebugMode = false;
#endif
BOOL g_isHeadlessMode = false;
INT32 Run(IN CONST String &name, IN CONST String &packageName, IN CONST String &developerName,
IN CONST String &publisherName, IN IA_VERSION_TYPE version)
{
INT32 frameCounter{0};
g_gameName = name;
g_gameVersion = version;
g_gamePackageName = packageName;
g_gameDeveloperName = developerName;
g_gamePublisherName = publisherName;
const auto config = Game_GetConfigRequest();
g_designViewport.x = config->DesignWidth;
g_designViewport.y = config->DesignHeight;
IAE_LOG_INFO("Booting IAEngine for ", g_gameName);
SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeRight");
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_gameName.c_str(), config->WindowWidth, config->WindowHeight,
SDL_WINDOW_RESIZABLE)))
THROW_UNKNOWN("Failed to create the SDL window: ", SDL_GetError());
#if __ANDROID__
SDL_SetWindowFullscreen(g_windowHandle, true);
#endif
const auto gameVersion = g_gameVersion;
SDL_SetAppMetadata(g_gameName.c_str(), IA_STRINGIFY_VERSION(gameVersion).c_str(), g_gamePackageName.c_str());
// EmbeddedResources::Initialize();
IAEngine::__Initialize("./Assets/");
SDL_Event event{};
while (true)
{
SDL_PollEvent(&event);
if (event.type == SDL_EVENT_QUIT)
break;
IAEngine::__ProcessEvent(&event);
IAEngine::__Update();
frameCounter++;
if (frameCounter >= 60)
{
frameCounter = 0;
IAEngine::__FixedUpdate();
}
IAEngine::__RenderToWindow();
}
IAEngine::__Terminate();
// EmbeddedResources::Terminate();
SDL_DestroyWindow(g_windowHandle);
IAE_LOG_INFO("Shutting down IAEngine");
return 0;
}
} // namespace ia::iae
namespace ia::iae
{
VOID IAEngine::__Initialize(IN CONST String& assetDirectory)
{
g_isHeadlessMode = false;
RDC::Initialize(IVec2{g_designViewport.x, g_designViewport.y}, g_windowHandle, g_isDebugMode);
g_defaultAssetManager = new AssetManager();
g_assetManager = g_defaultAssetManager;
g_assetManager->SetAssetDirectory(assetDirectory);
GameData::Initialize();
ChangeActiveScene(GameData::GetEntryScene()
? GameData::GetEntryScene()
: g_assetManager->CreateScene({g_designViewport.x, g_designViewport.y}));
Game_OnInitialize();
for (auto &p : g_plugins)
p->OnInitialize();
}
VOID IAEngine::__InitializeHeadless(IN CONST String& assetDirectory)
{
g_isHeadlessMode = true;
if (!g_designViewport.x || !g_designViewport.y)
g_designViewport = {800, 600};
g_defaultAssetManager = new AssetManager();
g_assetManager = g_defaultAssetManager;
g_assetManager->SetAssetDirectory(assetDirectory);
GameData::Initialize();
ChangeActiveScene(GameData::GetEntryScene()
? GameData::GetEntryScene()
: g_assetManager->CreateScene({g_designViewport.x, g_designViewport.y}));
Game_OnInitialize();
for (auto &p : g_plugins)
p->OnInitialize();
}
VOID IAEngine::__Terminate()
{
for (auto &p : g_plugins)
p->OnTerminate();
Game_OnTerminate();
GameData::Terminate();
delete g_defaultAssetManager;
RDC::Terminate();
}
VOID IAEngine::__RenderToWindow()
{
g_activeScene->GetScene().OnDraw();
RDC::RenderToWindow();
g_activeScene->GetScene().OnDebugDraw();
Game_OnDebugDraw();
for (auto &p : g_plugins)
p->OnDebugDraw();
}
VOID IAEngine::__RenderToTexture(IN PVOID textureHandle)
{
g_activeScene->GetScene().OnDraw();
RDC::RenderToTexture((SDL_GPUTexture *) textureHandle);
g_activeScene->GetScene().OnDebugDraw();
Game_OnDebugDraw();
for (auto &p : g_plugins)
p->OnDebugDraw();
}
VOID IAEngine::__Update()
{
FLOAT32 deltaTime = 0;
g_activeScene->GetScene().OnUpdate(deltaTime);
Game_OnUpdate(deltaTime);
for (auto &p : g_plugins)
p->OnUpdate(deltaTime);
}
VOID IAEngine::__FixedUpdate()
{
g_activeScene->GetScene().OnFixedUpdate();
Game_OnFixedUpdate();
for (auto &p : g_plugins)
p->OnFixedUpdate();
}
VOID IAEngine::__ProcessEvent(IN PVOID _event)
{
const auto event = (SDL_Event *) _event;
}
VOID IAEngine::AddPlugin(IN Asset_Plugin *plugin)
{
g_plugins.pushBack(plugin);
}
AssetManager* IAEngine::GetAssetManager()
{
return g_assetManager;
}
VOID IAEngine::SetAssetManager(IN AssetManager *instance)
{
g_assetManager = instance;
}
} // namespace ia::iae
namespace ia::iae
{
VOID IAEngine::DrawTile(IN Asset_TileSheet *tileSheet, IN INT32 tileIndexX, IN INT32 tileIndexY, IN Vec2 position,
IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH, IN BOOL flipV, IN Vec2 uvOffset)
{
RDC::DrawSpriteTopLeft(tileSheet->GetTexture(), tileIndexX, tileIndexY, position, scale, rotation, flipH, flipV,
uvOffset);
}
VOID IAEngine::DrawSprite(IN Asset_Sprite *sprite, IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation,
IN BOOL flipH, IN BOOL flipV, IN Vec2 uvOffset)
{
RDC::DrawSpriteTopLeft(sprite->GetTexture(), 0, 0, position, scale, rotation, flipH, flipV, uvOffset);
}
VOID IAEngine::DrawSprite(IN Asset_SpriteSheet *spriteSheet, IN INT32 animationIndex, IN INT32 frameIndex,
IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH, IN BOOL flipV,
IN Vec2 uvOffset)
{
RDC::DrawSpriteTopLeft(spriteSheet->GetTexture(), frameIndex, animationIndex, position, scale, rotation, flipH,
flipV, uvOffset);
}
} // namespace ia::iae
namespace ia::iae
{
Asset_Scene *IAEngine::GetActiveScene()
{
return g_activeScene;
}
VOID IAEngine::ChangeActiveScene(IN Asset_Scene *scene)
{
g_activeScene = scene;
}
} // namespace ia::iae