diff --git a/Samples/RPG/Resources/Scenes/GameMap.xml b/Samples/RPG/Resources/Scenes/GameMap.xml
index 1c597bf..05b5b9f 100644
--- a/Samples/RPG/Resources/Scenes/GameMap.xml
+++ b/Samples/RPG/Resources/Scenes/GameMap.xml
@@ -25,7 +25,83 @@
-
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+
+ |
+
+
+ |
+
+ |
+ |
+ |
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+ |
+ |
+ |
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+ |
+ |
+ |
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
|
diff --git a/Samples/RPG/Src/imp/cpp/Game.cpp b/Samples/RPG/Src/imp/cpp/Game.cpp
index ae7927b..bb8d73b 100644
--- a/Samples/RPG/Src/imp/cpp/Game.cpp
+++ b/Samples/RPG/Src/imp/cpp/Game.cpp
@@ -75,7 +75,7 @@ namespace ia::iae::rpg
VOID OnUpdate(IN FLOAT32 deltaTime)
{
- //IAEngine::DrawSprite(g_playerSpriteSheet, 2, 0, {100.0f, 100.0f}, {1.0f, 1.0f}, 0.0f);
+ //IAEngine::DrawSprite(0, 2, 0, {100.0f, 100.0f}, {1.0f, 1.0f}, 0.0f);
}
VOID OnResize(IN INT32 newWidth, IN INT32 newHeight)
diff --git a/Src/IAEngine/imp/cpp/GameData.cpp b/Src/IAEngine/imp/cpp/GameData.cpp
index 78e8abc..a92d421 100644
--- a/Src/IAEngine/imp/cpp/GameData.cpp
+++ b/Src/IAEngine/imp/cpp/GameData.cpp
@@ -19,8 +19,81 @@
#include
+#include
+
namespace ia::iae
{
+ class XMLData
+ {
+ public:
+ STATIC XMLData *Load(IN CONST String &path);
+
+ CONST String Type;
+ CONST String Name;
+ CONST pugi::xml_node PropertiesNode;
+ CONST Vector ChildNodes;
+
+ private:
+ CONST pugi::xml_document m_document;
+
+ XMLData(IN pugi::xml_document &&document, IN CONST String &type, IN CONST String &name,
+ IN pugi::xml_node propertiesNode, IN CONST Vector &childNodes);
+ };
+
+ XMLData::XMLData(IN pugi::xml_document &&document, IN CONST String &type, IN CONST String &name,
+ IN pugi::xml_node propertiesNode, IN CONST Vector &childNodes)
+ : m_document(IA_MOVE(document)), Type(type), Name(name), PropertiesNode(propertiesNode), ChildNodes(childNodes)
+ {
+ }
+
+ XMLData *XMLData::Load(IN CONST String &path)
+ {
+ pugi::xml_document doc;
+ if (!doc.load_file(path.c_str()))
+ return nullptr;
+
+ if (std::distance(doc.children().begin(), doc.children().end()) != 1)
+ return nullptr;
+ const auto rootNode = *doc.children().begin();
+
+ // Verify Engine Version
+ {
+ const auto engineInfoNode = rootNode.child("IAEngine");
+ if (!engineInfoNode)
+ return nullptr;
+ const auto engineVersionNode = engineInfoNode.child("EngineVersion");
+ if (!engineVersionNode)
+ return nullptr;
+ const auto engineVersion = IA_PARSE_VERSION_STRING(engineVersionNode.text().as_string());
+ if (engineVersion > IAEngine::ENGINE_VERSION)
+ {
+ IAE_LOG_WARN("XML data file was created with a newer version of IAEngine, skipping..");
+ return nullptr;
+ }
+ }
+
+ const auto propertiesNode = rootNode.child("Properties");
+ if (!propertiesNode)
+ return nullptr;
+
+ Vector childNodes;
+ for (auto &c : rootNode.children())
+ {
+ if ((!strcmp(c.name(), "Properties")) || (!strcmp(c.name(), "IAEngine")))
+ continue;
+ childNodes.pushBack(c);
+ }
+
+ const auto nameAttr = rootNode.attribute("name");
+ return new XMLData(IA_MOVE(doc), rootNode.name(), nameAttr ? nameAttr.as_string() : "", propertiesNode,
+ childNodes);
+ }
+} // namespace ia::iae
+
+namespace ia::iae
+{
+ RefPtr g_entryScene{};
+
VOID GameData::Initialize()
{
if (!LoadResourceData())
@@ -41,17 +114,155 @@ namespace ia::iae
BOOL GameData::LoadSceneData()
{
+ for (const auto &entry : std::filesystem::directory_iterator("Resources/Scenes/"))
+ {
+ const auto scene = ParseScene(entry.path().string().c_str());
+ if (!scene)
+ {
+ IAE_LOG_WARN("Failed to load the scene \"", entry.path().string().c_str(), "\", skipping..");
+ continue;
+ }
+ }
return true;
}
BOOL GameData::LoadResourceData()
{
-
+ auto xml = XMLData::Load("Resources/Resources.xml");
+ if (!xml)
+ return false;
+
+ pugi::xml_node entriesNode{};
+ for (const auto &node : xml->ChildNodes)
+ {
+ if (!strcmp(node.name(), "Entries"))
+ {
+ entriesNode = node;
+ break;
+ }
+ }
+ if (!entriesNode)
+ return false;
+
+ for (const auto &entry : entriesNode.children())
+ {
+ if (!strcmp(entry.name(), "Sprite"))
+ {
+ }
+ else if (!strcmp(entry.name(), "SpriteSheet"))
+ {
+ }
+ else if (!strcmp(entry.name(), "TileSheet"))
+ {
+ IAEngine::AssignResourceName(
+ IAEngine::CreateTileSheet(BuildString("Resources/", entry.attribute("path").as_string()),
+ entry.attribute("tileWidth").as_int(),
+ entry.attribute("tileHeight").as_int()),
+ entry.attribute("name").as_string());
+ }
+ else
+ THROW_INVALID_DATA();
+ }
+
+ delete xml;
return true;
}
+ RefPtr GameData::ParseScene(IN CONST String &path)
+ {
+ const auto xml = XMLData::Load(path);
+ if (!xml)
+ return nullptr;
+
+ const auto extentNode = xml->PropertiesNode.child("Extent");
+ if (!extentNode)
+ return nullptr;
+
+ const auto extent = IVec2{extentNode.attribute("width").as_int(), extentNode.attribute("height").as_int()};
+ RefPtr scene = MakeRefPtr(extent);
+
+ for (const auto &child : xml->ChildNodes)
+ {
+ if (!strcmp(child.name(), "Resources"))
+ {
+ for (const auto &r : child.children())
+ scene->AddReferencedResources(IAEngine::GetResourceByName(r.attribute("name").as_string()));
+ }
+ else if (!strcmp(child.name(), "Nodes"))
+ {
+ }
+ else if (!strcmp(child.name(), "Grid"))
+ {
+ ParseSceneGrid(scene.get(), &child);
+ }
+ else
+ THROW_INVALID_DATA();
+ }
+
+ IAEngine::AssignResourceName(IAEngine::AddScene(scene), xml->Name);
+
+ if (!g_entryScene)
+ g_entryScene = scene;
+
+ return scene;
+ }
+
+ VOID GameData::ParseSceneGrid(IN Scene *scene, IN PCVOID _gridNode)
+ {
+ const auto gridNode = *static_cast(_gridNode);
+
+ const auto parseHexColor = [](IN PCCHAR hex) -> Vec4
+ {
+ Vec4 result{1.0f, 1.0f, 1.0f, 1.0f};
+ if((hex[0] != '#') || (strlen(hex) != 9))return result;
+ THROW_NOT_IMPLEMENTED();
+ return result;
+ };
+
+ INT32 tileCursorX{}, tileCursorY{};
+ const auto processCell = [&](IN pugi::xml_node cellNode) {
+ if B_UNLIKELY (tileCursorY >= scene->GetGridSize().y)
+ return;
+
+ auto& cell = scene->GetGridCell(tileCursorX, tileCursorY);
+ cell.TileSheetTexture = IAEngine::GetResourceByName(cellNode.attribute("tileSheet").as_string());
+ cell.TileIndex.x = cellNode.attribute("tileX").as_int();
+ cell.TileIndex.y = cellNode.attribute("tileY").as_int();
+ cell.CollisionMask = cellNode.attribute("collisionMask").as_ullong();
+ //cell.ColorOverlay = parseHexColor(cellNode.attribute("colorOverlay").as_string());
+
+ tileCursorX++;
+ if (tileCursorX >= scene->GetGridSize().x)
+ {
+ tileCursorX = 0;
+ tileCursorY++;
+ }
+ };
+
+ scene->SetupGrid({gridNode.attribute("tileWidth").as_int(), gridNode.attribute("tileHeight").as_int()});
+
+ for (const auto &t : gridNode.children())
+ {
+ if (!strcmp(t.name(), "Cell"))
+ {
+ processCell(t);
+ }
+ else if (!strcmp(t.name(), "Repeat"))
+ {
+ const auto count = t.attribute("times").as_int();
+ for (INT32 i = 0; i < count; i++)
+ {
+ for (const auto &cellNode : t)
+ processCell(cellNode);
+ }
+ }
+ else
+ THROW_INVALID_DATA();
+ }
+ }
+
RefPtr GameData::GetEntryScene()
{
- return nullptr;
+ return g_entryScene;
}
} // namespace ia::iae
diff --git a/Src/IAEngine/imp/cpp/IAEngine.cpp b/Src/IAEngine/imp/cpp/IAEngine.cpp
index 3e59a4b..286b8f1 100644
--- a/Src/IAEngine/imp/cpp/IAEngine.cpp
+++ b/Src/IAEngine/imp/cpp/IAEngine.cpp
@@ -15,9 +15,9 @@
// along with this program. If not, see .
#include
+#include
#include
#include
-#include
#define STB_IMAGE_IMPLEMENTATION
#include
@@ -32,7 +32,8 @@ namespace ia::iae
TEXTURE,
SPRITE_SHEET,
- SOUND
+ SOUND,
+ SCENE
};
EType Type{EType::INVALID};
@@ -48,6 +49,11 @@ namespace ia::iae
Vector FrameCounts;
};
+ struct Resource_Scene : public Resource
+ {
+ RefPtr SceneRef;
+ };
+
RefPtr g_activeScene;
Vector g_resources;
Map g_resourceNames;
@@ -146,9 +152,17 @@ namespace ia::iae
{
Renderer::Initialize(IVec2{g_designViewport.x, g_designViewport.y});
+ { // Add default texture to resources
+ const auto t = new Resource_Texture();
+ t->Type = Resource::EType::TEXTURE;
+ t->Texture = 0;
+ g_resources.pushBack(t);
+ }
+
GameData::Initialize();
- ChangeActiveScene(GameData::GetEntryScene() ? GameData::GetEntryScene() : CreateScene({g_designViewport.x, g_designViewport.y}));
+ ChangeActiveScene(GameData::GetEntryScene() ? GameData::GetEntryScene()
+ : CreateScene({g_designViewport.x, g_designViewport.y}));
Game_OnInitialize();
}
@@ -203,6 +217,8 @@ namespace ia::iae
{
INT32 w, h, n;
auto pixels = stbi_load(path, &w, &h, &n, STBI_rgb_alpha);
+ if (!pixels)
+ THROW_INVALID_DATA(path);
const auto t = Renderer::CreateTexture(pixels, w, h, tileWidth == -1 ? 1 : w / tileWidth,
tileHeight == -1 ? 1 : h / tileHeight);
stbi_image_free(pixels);
@@ -280,6 +296,10 @@ namespace ia::iae
case Resource::EType::SOUND:
break;
+
+ case Resource::EType::SCENE:
+ static_cast(g_resources[resource])->SceneRef.reset();
+ break;
}
delete g_resources[resource];
g_resources[resource] = nullptr;
@@ -307,6 +327,7 @@ namespace ia::iae
{
switch (g_resources[handle]->Type)
{
+ case Resource::EType::SCENE:
case Resource::EType::INVALID:
break;
@@ -367,4 +388,18 @@ namespace ia::iae
g_activeScene = scene;
LoadResources(scene->GetReferencedResources());
}
+
+ VOID IAEngine::ChangeActiveScene(IN Handle scene)
+ {
+ ChangeActiveScene(static_cast(g_resources[scene])->SceneRef);
+ }
+
+ Handle IAEngine::AddScene(IN RefPtr scene)
+ {
+ const auto t = new Resource_Scene();
+ t->Type = Resource::EType::SCENE;
+ t->SceneRef = scene;
+ g_resources.pushBack(t);
+ return (Handle) g_resources.size() - 1;
+ }
} // namespace ia::iae
\ No newline at end of file
diff --git a/Src/IAEngine/imp/cpp/Scene.cpp b/Src/IAEngine/imp/cpp/Scene.cpp
index ec654e5..5e4bb27 100644
--- a/Src/IAEngine/imp/cpp/Scene.cpp
+++ b/Src/IAEngine/imp/cpp/Scene.cpp
@@ -14,8 +14,8 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
-#include
#include
+#include
namespace ia::iae
{
@@ -36,11 +36,22 @@ namespace ia::iae
VOID Scene::OnDraw()
{
- for(const auto& cell: m_gridCells)
+ INT32 tileCursorX{}, tileCursorY{};
+ for (const auto &cell : m_gridCells)
{
- IAEngine::DrawTile(cell.TileSheetTexture, cell.TileIndex.x, cell.TileIndex.y, {
-
- }, {1.0f, 1.0f}, 0.0f);
+ if (cell.TileSheetTexture)
+ IAEngine::DrawTile(cell.TileSheetTexture, cell.TileIndex.x, cell.TileIndex.y,
+ {
+ tileCursorX * m_gridCellSize.x,
+ tileCursorY * m_gridCellSize.y
+ },
+ {1.0f, 1.0f}, 0.0f);
+ tileCursorX++;
+ if (tileCursorX >= GetGridSize().x)
+ {
+ tileCursorX = 0;
+ tileCursorY++;
+ }
}
}
diff --git a/Src/IAEngine/imp/hpp/GameData.hpp b/Src/IAEngine/imp/hpp/GameData.hpp
index fe5e5e9..8645422 100644
--- a/Src/IAEngine/imp/hpp/GameData.hpp
+++ b/Src/IAEngine/imp/hpp/GameData.hpp
@@ -29,6 +29,9 @@ namespace ia::iae
STATIC BOOL LoadSceneData();
STATIC BOOL LoadResourceData();
+ STATIC RefPtr ParseScene(IN CONST String& path);
+ STATIC VOID ParseSceneGrid(IN Scene* scene, IN PCVOID gridNode);
+
private:
STATIC VOID Initialize();
STATIC VOID Terminate();
diff --git a/Src/IAEngine/inc/IAEngine/IAEngine.hpp b/Src/IAEngine/inc/IAEngine/IAEngine.hpp
index 82c45ef..7f68b02 100644
--- a/Src/IAEngine/inc/IAEngine/IAEngine.hpp
+++ b/Src/IAEngine/inc/IAEngine/IAEngine.hpp
@@ -22,6 +22,9 @@ namespace ia::iae
{
class IAEngine
{
+ public:
+ STATIC CONSTEXPR IA_VERSION_TYPE ENGINE_VERSION = IA_MAKE_VERSION(1, 0, 0);
+
public:
STATIC Handle CreateSprite(IN CONST String &path);
STATIC Handle CreateSprite(IN PCUINT8 rgbaData, IN INT32 width, IN INT32 height);
@@ -43,6 +46,8 @@ namespace ia::iae
public:
STATIC RefPtr GetActiveScene();
STATIC RefPtr CreateScene(IN IVec2 extent);
+ STATIC VOID ChangeActiveScene(IN Handle scene);
+ STATIC Handle AddScene(IN RefPtr scene);
STATIC VOID ChangeActiveScene(IN RefPtr scene);
public:
diff --git a/Src/IAEngine/inc/IAEngine/Scene.hpp b/Src/IAEngine/inc/IAEngine/Scene.hpp
index 874a508..c0baf88 100644
--- a/Src/IAEngine/inc/IAEngine/Scene.hpp
+++ b/Src/IAEngine/inc/IAEngine/Scene.hpp
@@ -41,7 +41,26 @@ namespace ia::iae
INLINE GridCell &GetGridCell(IN INT32 x, IN INT32 y);
INLINE VOID AddReferencedResources(IN Handle resource);
- INLINE CONST Vector &GetReferencedResources() CONST;
+ public:
+ CONST Vector &GetReferencedResources() CONST
+ {
+ return m_referencedResources;
+ }
+
+ CONST IVec2 &GetGridSize() CONST
+ {
+ return m_gridSize;
+ }
+
+ CONST IVec2 &GetExtent() CONST
+ {
+ return m_extent;
+ }
+
+ CONST IVec2 &GetGridCellSize() CONST
+ {
+ return m_gridCellSize;
+ }
private:
IVec2 m_gridSize{};
@@ -69,9 +88,4 @@ namespace ia::iae
{
m_referencedResources.pushBack(resource);
}
-
- CONST Vector &Scene::GetReferencedResources() CONST
- {
- return m_referencedResources;
- }
} // namespace ia::iae
diff --git a/Vendor/IACore b/Vendor/IACore
index 2498e7d..cdc4413 160000
--- a/Vendor/IACore
+++ b/Vendor/IACore
@@ -1 +1 @@
-Subproject commit 2498e7d6e3f5712b28f2c0cdc267b929e6de09b9
+Subproject commit cdc44137e8fe70209f3b2fa048586d36d1e703b7