279 lines
8.0 KiB
C++
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
|