SpriteSheet and Tiles

This commit is contained in:
Isuru Samarathunga
2025-11-02 15:49:47 +05:30
parent 9fafab5145
commit 7d69518bdc
5 changed files with 266 additions and 56 deletions

View File

@ -29,12 +29,20 @@ namespace ia::iae::rpg
return &EngineConfig; return &EngineConfig;
} }
Handle g_playerSpriteSheet;
VOID OnInitialize() VOID OnInitialize()
{ {
g_playerSpriteSheet = IAEngine::CreateSpriteSheet("Resources/Cute_Fantasy_Free/Player/Player.png", 32, 32,
{6, 6, 6, 6, 6, 6, 4, 4, 4, 4});
IAEngine::LoadResources({g_playerSpriteSheet});
} }
VOID OnTerminate() VOID OnTerminate()
{ {
IAEngine::DestroyResource(g_playerSpriteSheet);
} }
VOID OnDebugDraw() VOID OnDebugDraw()
@ -47,6 +55,7 @@ namespace ia::iae::rpg
VOID OnUpdate(IN FLOAT32 deltaTime) VOID OnUpdate(IN FLOAT32 deltaTime)
{ {
IAEngine::DrawSprite(g_playerSpriteSheet, 0, 0, {100.0f, 100.0f});
} }
VOID OnResize(IN INT32 newWidth, IN INT32 newHeight) VOID OnResize(IN INT32 newWidth, IN INT32 newHeight)

View File

@ -21,6 +21,35 @@
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include <Vendor/stb/stb_image.h> #include <Vendor/stb/stb_image.h>
namespace ia::iae
{
struct Resource
{
enum class EType
{
INVALID,
TEXTURE,
SPRITE_SHEET,
SOUND
};
EType Type{EType::INVALID};
};
struct Resource_Texture : public Resource
{
Handle Texture;
};
struct Resource_SpriteSheet : public Resource_Texture
{
Vector<INT32> FrameCounts;
};
Vector<Resource *> g_resources;
} // namespace ia::iae
namespace ia::iae namespace ia::iae
{ {
String g_gameName; String g_gameName;
@ -98,38 +127,26 @@ namespace ia::iae
namespace ia::iae namespace ia::iae
{ {
Handle CreateTexture(IN PCCHAR path, IN INT32 tileWidth = -1, IN INT32 tileHeight = -1)
{
INT32 w, h, n;
auto pixels = stbi_load(path, &w, &h, &n, STBI_rgb_alpha);
const auto t = Renderer::CreateTexture(pixels, w, h, tileWidth == -1 ? 1 : w/tileWidth, tileHeight == -1 ? 1 : h/tileHeight);
stbi_image_free(pixels);
return t;
}
Handle textures[5];
VOID IAEngine::Initialize() VOID IAEngine::Initialize()
{ {
Renderer::Initialize(IVec2{g_designViewport.x, g_designViewport.y}); Renderer::Initialize(IVec2{g_designViewport.x, g_designViewport.y});
textures[0] = CreateTexture("Resources/Cute_Fantasy_Free/Tiles/Beach_Tile.png", 16, 16); Game_OnInitialize();
textures[1] = CreateTexture("Resources/Cute_Fantasy_Free/Tiles/Cliff_Tile.png", 16, 16);
Renderer::SetTextureAtlas({textures[0], textures[1]});
} }
VOID IAEngine::Terminate() VOID IAEngine::Terminate()
{ {
Game_OnTerminate();
Renderer::Terminate(); Renderer::Terminate();
for (SIZE_T i = 0; i < g_resources.size(); i++)
DestroyResource(i);
} }
VOID IAEngine::Update() VOID IAEngine::Update()
{ {
Renderer::DrawStaticSpriteTopLeft(textures[1], 0, {0.0f, 0.0f}, {1.0f, 1.0f}, 0.0f); Game_OnUpdate(0.0f);
Renderer::DrawStaticSpriteTopLeft(textures[1], 1, {16.0f, 0.0f}, {1.0f, 1.0f}, 0.0f);
Renderer::DrawStaticSpriteTopLeft(textures[1], 2, {32.0f, 0.0f}, {1.0f, 1.0f}, 0.0f);
Renderer::Update(); Renderer::Update();
} }
@ -138,3 +155,139 @@ namespace ia::iae
const auto event = (SDL_Event *) _event; const auto event = (SDL_Event *) _event;
} }
} // namespace ia::iae } // namespace ia::iae
namespace ia::iae
{
Handle CreateTextureFromFile(IN PCCHAR path, IN INT32 tileWidth = -1, IN INT32 tileHeight = -1)
{
INT32 w, h, n;
auto pixels = stbi_load(path, &w, &h, &n, STBI_rgb_alpha);
const auto t = Renderer::CreateTexture(pixels, w, h, tileWidth == -1 ? 1 : w / tileWidth,
tileHeight == -1 ? 1 : h / tileHeight);
stbi_image_free(pixels);
return t;
}
Handle IAEngine::CreateSprite(IN CONST String &path)
{
const auto t = new Resource_Texture();
t->Type = Resource::EType::TEXTURE;
t->Texture = CreateTextureFromFile(path.c_str());
g_resources.pushBack(t);
return (Handle)g_resources.size() - 1;
}
Handle IAEngine::CreateSprite(IN PCUINT8 rgbaData, IN INT32 width, IN INT32 height)
{
const auto t = new Resource_Texture();
t->Type = Resource::EType::TEXTURE;
t->Texture = Renderer::CreateTexture(rgbaData, width, height);
g_resources.pushBack(t);
return (Handle)g_resources.size() - 1;
}
Handle IAEngine::CreateSpriteSheet(IN CONST Vector<Vector<Handle>> &animations)
{
THROW_NOT_IMPLEMENTED();
return INVALID_HANDLE;
}
Handle IAEngine::CreateSpriteSheet(IN CONST String &path, IN INT32 spriteWidth, IN INT32 spriteHeight,
IN CONST Vector<INT32> &frameCounts)
{
const auto t = new Resource_SpriteSheet();
t->Type = Resource::EType::SPRITE_SHEET;
t->FrameCounts = frameCounts;
t->Texture = CreateTextureFromFile(path.c_str(), spriteWidth, spriteHeight);
g_resources.pushBack(t);
return (Handle)g_resources.size() - 1;
}
Handle IAEngine::CreateTileSheet(IN CONST String &path, IN INT32 tileWidth, IN INT32 tileHeight)
{
const auto t = new Resource_Texture();
t->Type = Resource::EType::TEXTURE;
t->Texture = CreateTextureFromFile(path.c_str(), tileWidth, tileHeight);
g_resources.pushBack(t);
return (Handle)g_resources.size() - 1;
}
Handle IAEngine::CreateTileSheet(IN PCUINT8 rgbaData, IN INT32 width, IN INT32 height, IN INT32 tileWidth,
IN INT32 tileHeight)
{
const auto t = new Resource_Texture();
t->Type = Resource::EType::TEXTURE;
t->Texture = Renderer::CreateTexture(rgbaData, width, height, width / tileWidth, height / tileHeight);
g_resources.pushBack(t);
return (Handle)g_resources.size() - 1;
}
VOID IAEngine::DestroyResource(IN Handle resource)
{
if(!g_resources[resource]) return;
switch (g_resources[resource]->Type)
{
case Resource::EType::INVALID:
break;
case Resource::EType::TEXTURE:
case Resource::EType::SPRITE_SHEET:
Renderer::DestroyTexture(static_cast<Resource_Texture *>(g_resources[resource])->Texture);
break;
case Resource::EType::SOUND:
break;
}
delete g_resources[resource];
g_resources[resource] = nullptr;
}
VOID IAEngine::LoadResources(IN CONST Vector<Handle> &resources)
{
Vector<Handle> atlasTextures;
for (const auto &handle : resources)
{
switch (g_resources[handle]->Type)
{
case Resource::EType::INVALID:
break;
case Resource::EType::TEXTURE:
case Resource::EType::SPRITE_SHEET:
atlasTextures.pushBack(static_cast<Resource_Texture *>(g_resources[handle])->Texture);
break;
case Resource::EType::SOUND:
break;
}
}
Renderer::BakeTextureAtlas(atlasTextures);
}
} // namespace ia::iae
namespace ia::iae
{
VOID IAEngine::DrawTile(IN Handle 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)
{
const auto t = static_cast<Resource_Texture*>(g_resources[tileSheet]);
Renderer::DrawStaticSpriteTopLeft(t->Texture, tileIndexX, tileIndexY, position, scale, rotation, flipH, flipV, uvOffset);
}
VOID IAEngine::DrawSprite(IN Handle sprite, IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH,
IN BOOL flipV, IN Vec2 uvOffset)
{
const auto t = static_cast<Resource_Texture*>(g_resources[sprite]);
Renderer::DrawDynamicSpriteTopLeft(t->Texture, 0, 0, position, scale, rotation, flipH, flipV, uvOffset);
}
VOID IAEngine::DrawSprite(IN Handle 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)
{
const auto t = static_cast<Resource_SpriteSheet*>(g_resources[spriteSheet]);
Renderer::DrawDynamicSpriteTopLeft(t->Texture, animationIndex, frameIndex, position, scale, rotation, flipH, flipV, uvOffset);
}
} // namespace ia::iae

View File

@ -204,26 +204,58 @@ namespace ia::iae
namespace ia::iae namespace ia::iae
{ {
VOID Renderer::DrawStaticSpriteTopLeft(IN Handle texture, IN INT32 tileIndex, IN Vec2 position, IN Vec2 scale, Vec2 Renderer::DrawStaticSpriteTopLeft(IN Handle texture, IN INT32 tileIndexX, IN INT32 tileIndexY,
IN FLOAT32 rotation) IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH, IN BOOL flipV, IN Vec2 uvOffset)
{ {
const auto _s = Vec2{scale.x * g_texureData[texture].TileWidth, scale.y * g_texureData[texture].TileHeight};
Mat4 transform = glm::translate(glm::mat4(1.0f), glm::vec3{position.x, position.y, 0}); Mat4 transform = glm::translate(glm::mat4(1.0f), glm::vec3{position.x, position.y, 0});
transform = glm::rotate(transform, rotation, glm::vec3(0.0f, 0.0f, 1.0f)); transform = glm::rotate(transform, rotation, glm::vec3(0.0f, 0.0f, 1.0f));
transform = glm::scale(transform, glm::vec3{scale.x * g_texureData[texture].TileWidth, scale.y * g_texureData[texture].TileHeight, 1.0f}); transform = glm::scale(transform, glm::vec3(_s, 1.0f));
g_staticSprites.pushBack({.Transform = transform, g_staticSprites.pushBack({.Transform = transform,
.TexCoords = GetTextureAtlasCoordinates(texture, tileIndex), .TexCoords = GetTextureAtlasCoordinates(texture, tileIndexX, tileIndexY, flipH, flipV, uvOffset),
.Color = {1.0f, 1.0f, 1.0f, 1.0f}}); .Color = {1.0f, 1.0f, 1.0f, 1.0f}});
return _s;
} }
VOID Renderer::DrawDynamicSpriteTopLeft(IN Handle texture, IN INT32 tileIndex, IN Vec2 position, IN Vec2 scale, Vec2 Renderer::DrawStaticSpriteCentered(IN Handle texture, IN INT32 tileIndexX, IN INT32 tileIndexY,
IN FLOAT32 rotation) IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH, IN BOOL flipV, IN Vec2 uvOffset)
{ {
const auto _s = Vec2{scale.x * g_texureData[texture].TileWidth, scale.y * g_texureData[texture].TileHeight};
Mat4 transform =
glm::translate(glm::mat4(1.0f), glm::vec3{position.x - _s.x / 2.0f, position.y - _s.y / 2.0f, 0});
transform = glm::rotate(transform, rotation, glm::vec3(0.0f, 0.0f, 1.0f));
transform = glm::scale(transform, glm::vec3(_s, 1.0f));
g_staticSprites.pushBack({.Transform = transform,
.TexCoords = GetTextureAtlasCoordinates(texture, tileIndexX, tileIndexY, flipH, flipV, uvOffset),
.Color = {1.0f, 1.0f, 1.0f, 1.0f}});
return _s;
}
Vec2 Renderer::DrawDynamicSpriteTopLeft(IN Handle texture, IN INT32 tileIndexX, IN INT32 tileIndexY,
IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH, IN BOOL flipV, IN Vec2 uvOffset)
{
const auto _s = Vec2{scale.x * g_texureData[texture].TileWidth, scale.y * g_texureData[texture].TileHeight};
Mat4 transform = glm::translate(glm::mat4(1.0f), glm::vec3{position.x, position.y, 0}); Mat4 transform = glm::translate(glm::mat4(1.0f), glm::vec3{position.x, position.y, 0});
transform = glm::rotate(transform, rotation, glm::vec3(0.0f, 0.0f, 1.0f)); transform = glm::rotate(transform, rotation, glm::vec3(0.0f, 0.0f, 1.0f));
transform = glm::scale(transform, glm::vec3{scale.x * g_texureData[texture].TileWidth, scale.y * g_texureData[texture].TileHeight, 1.0f}); transform = glm::scale(transform, glm::vec3{_s, 1.0f});
g_dynamicSprites.pushBack({.Transform = transform, g_dynamicSprites.pushBack({.Transform = transform,
.TexCoords = GetTextureAtlasCoordinates(texture, tileIndex), .TexCoords = GetTextureAtlasCoordinates(texture, tileIndexX, tileIndexY, flipH, flipV, uvOffset),
.Color = {1.0f, 1.0f, 1.0f, 1.0f}}); .Color = {1.0f, 1.0f, 1.0f, 1.0f}});
return _s;
}
Vec2 Renderer::DrawDynamicSpriteCentered(IN Handle texture, IN INT32 tileIndexX, IN INT32 tileIndexY,
IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH, IN BOOL flipV, IN Vec2 uvOffset)
{
const auto _s = Vec2{scale.x * g_texureData[texture].TileWidth, scale.y * g_texureData[texture].TileHeight};
Mat4 transform =
glm::translate(glm::mat4(1.0f), glm::vec3{position.x - _s.x / 2.0f, position.y - _s.y / 2.0f, 0});
transform = glm::rotate(transform, rotation, glm::vec3(0.0f, 0.0f, 1.0f));
transform = glm::scale(transform, glm::vec3{_s, 1.0f});
g_dynamicSprites.pushBack({.Transform = transform,
.TexCoords = GetTextureAtlasCoordinates(texture, tileIndexX, tileIndexY, flipH, flipV, uvOffset),
.Color = {1.0f, 1.0f, 1.0f, 1.0f}});
return _s;
} }
Geometry *Renderer::CreateGeometry(IN CONST Vector<GeometryVertex> &vertices, IN CONST Vector<INT32> &indices) Geometry *Renderer::CreateGeometry(IN CONST Vector<GeometryVertex> &vertices, IN CONST Vector<INT32> &indices)
@ -284,7 +316,7 @@ namespace ia::iae
t.Height, t.Width, t.Pixels); t.Height, t.Width, t.Pixels);
} }
VOID Renderer::SetTextureAtlas(IN CONST Vector<Handle> textures) VOID Renderer::BakeTextureAtlas(IN CONST Vector<Handle> textures)
{ {
if (g_activeTextureAtlas && (g_activeTextureAtlas != g_defaultTexture)) if (g_activeTextureAtlas && (g_activeTextureAtlas != g_defaultTexture))
DestroyTexture(g_activeTextureAtlas); DestroyTexture(g_activeTextureAtlas);
@ -320,14 +352,12 @@ namespace ia::iae
delete[] pixels; delete[] pixels;
} }
Vec4 Renderer::GetTextureAtlasCoordinates(IN Handle texture, IN INT32 tileIndex) Vec4 Renderer::GetTextureAtlasCoordinates(IN Handle texture, IN INT32 tileIndexX, IN INT32 tileIndexY, IN BOOL flipH, IN BOOL flipV, IN Vec2 uvOffset)
{ {
const auto &d = g_texureData[texture]; const auto &d = g_texureData[texture];
const auto &t = g_activeTextureAtlasUVMap[texture]; const auto &t = g_activeTextureAtlasUVMap[texture];
const auto pX = const auto pX = (tileIndexX * ((FLOAT32) d.TileWidth)) * g_activeTextureAtlasInverseSize.x;
((INT32) (tileIndex % d.TileCountX) * ((FLOAT32) d.TileWidth)) * g_activeTextureAtlasInverseSize.x; const auto pY = (tileIndexY * ((FLOAT32) d.TileHeight)) * g_activeTextureAtlasInverseSize.y;
const auto pY =
((INT32) (tileIndex / d.TileCountX) * ((FLOAT32) d.TileHeight)) * g_activeTextureAtlasInverseSize.y;
return Vec4(t.x + pX, t.y + pY, d.TileWidth * g_activeTextureAtlasInverseSize.x, return Vec4(t.x + pX, t.y + pY, d.TileWidth * g_activeTextureAtlasInverseSize.x,
d.TileHeight * g_activeTextureAtlasInverseSize.y); d.TileHeight * g_activeTextureAtlasInverseSize.y);
} }

View File

@ -66,23 +66,26 @@ namespace ia::iae
STATIC VOID SetCameraPosition(IN Vec2 position); STATIC VOID SetCameraPosition(IN Vec2 position);
public: public:
STATIC VOID DrawStaticSpriteTopLeft(IN Handle texture, IN INT32 tileIndex, IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation); STATIC Vec2 DrawStaticSpriteTopLeft(IN Handle texture, IN INT32 tileIndexX, IN INT32 tileIndexY,
STATIC INLINE VOID DrawStaticSpriteCentered(IN Handle texture, IN INT32 tileIndex, IN Vec2 position, IN Vec2 scale, IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH = false, IN BOOL flipV = false, IN Vec2 uvOffset = {});
IN FLOAT32 rotation); STATIC Vec2 DrawStaticSpriteCentered(IN Handle texture, IN INT32 tileIndexX, IN INT32 tileIndexY,
IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH = false, IN BOOL flipV = false, IN Vec2 uvOffset = {});
STATIC VOID DrawDynamicSpriteTopLeft(IN Handle texture, IN INT32 tileIndex, IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation); STATIC Vec2 DrawDynamicSpriteTopLeft(IN Handle texture, IN INT32 tileIndexX, IN INT32 tileIndexY,
STATIC INLINE VOID DrawDynamicSpriteCentered(IN Handle texture, IN INT32 tileIndex, IN Vec2 position, IN Vec2 scale, IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH = false, IN BOOL flipV = false, IN Vec2 uvOffset = {});
IN FLOAT32 rotation); STATIC Vec2 DrawDynamicSpriteCentered(IN Handle texture, IN INT32 tileIndexX, IN INT32 tileIndexY,
IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH = false, IN BOOL flipV = false, IN Vec2 uvOffset = {});
STATIC VOID ResizeScreen(IN IVec2 newSize); STATIC VOID ResizeScreen(IN IVec2 newSize);
public: public:
STATIC Handle CreateTexture(IN PCUINT8 rgbaData, IN INT32 width, IN INT32 height, IN INT32 tileCountX = 1, IN INT32 tileCountY = 1); STATIC Handle CreateTexture(IN PCUINT8 rgbaData, IN INT32 width, IN INT32 height, IN INT32 tileCountX = 1,
IN INT32 tileCountY = 1);
STATIC VOID DestroyTexture(IN Handle texture); STATIC VOID DestroyTexture(IN Handle texture);
STATIC VOID BakeTexture(IN Handle texture); STATIC VOID BakeTexture(IN Handle texture);
STATIC VOID SetTextureAtlas(IN CONST Vector<Handle> textures); STATIC VOID BakeTextureAtlas(IN CONST Vector<Handle> textures);
private: private:
STATIC SDL_GPUTexture *CreateTexture(IN SDL_GPUTextureUsageFlags usage, IN INT32 width, IN INT32 height, STATIC SDL_GPUTexture *CreateTexture(IN SDL_GPUTextureUsageFlags usage, IN INT32 width, IN INT32 height,
@ -115,7 +118,7 @@ namespace ia::iae
STATIC VOID Render(); STATIC VOID Render();
STATIC Vec4 GetTextureAtlasCoordinates(IN Handle texture, IN INT32 tileIndex); STATIC Vec4 GetTextureAtlasCoordinates(IN Handle texture, IN INT32 tileIndexX, IN INT32 tileIndexY, IN BOOL flipH, IN BOOL flipV, IN Vec2 uvOffset);
private: private:
STATIC VOID Initialize(IN IVec2 screenExtent); STATIC VOID Initialize(IN IVec2 screenExtent);
@ -124,14 +127,4 @@ namespace ia::iae
friend class IAEngine; friend class IAEngine;
}; };
VOID Renderer::DrawStaticSpriteCentered(IN Handle texture,IN INT32 tileIndex, IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation)
{
DrawStaticSpriteTopLeft(texture, tileIndex, position - scale / 2.0f, scale, rotation);
}
VOID Renderer::DrawDynamicSpriteCentered(IN Handle texture,IN INT32 tileIndex, IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation)
{
DrawDynamicSpriteTopLeft(texture, tileIndex, position - scale / 2.0f, scale, rotation);
}
} // namespace ia::iae } // namespace ia::iae

View File

@ -23,6 +23,31 @@ namespace ia::iae
class IAEngine class IAEngine
{ {
public: public:
STATIC Handle CreateSprite(IN CONST String &path);
STATIC Handle CreateSprite(IN PCUINT8 rgbaData, IN INT32 width, IN INT32 height);
STATIC Handle CreateSpriteSheet(IN CONST Vector<Vector<Handle>> &animations);
STATIC Handle CreateSpriteSheet(IN CONST String &path, IN INT32 spriteWidth, IN INT32 spriteHeight,
IN CONST Vector<INT32> &frameCounts);
STATIC Handle CreateTileSheet(IN CONST String &path, IN INT32 tileWidth, IN INT32 tileHeight);
STATIC Handle CreateTileSheet(IN PCUINT8 rgbaData, IN INT32 width, IN INT32 height, IN INT32 tileWidth,
IN INT32 tileHeight);
STATIC VOID DestroyResource(IN Handle resource);
STATIC VOID LoadResources(IN CONST Vector<Handle> &resources);
public:
STATIC VOID DrawTile(IN Handle tileSheet, IN INT32 tileIndexX, IN INT32 tileIndexY, IN Vec2 position,
IN Vec2 scale = {1.0f, 1.0f}, IN FLOAT32 rotation = 0.0f, IN BOOL flipH = false,
IN BOOL flipV = false, IN Vec2 uvOffset = {});
STATIC VOID DrawSprite(IN Handle sprite, IN Vec2 position, IN Vec2 scale = {1.0f, 1.0f},
IN FLOAT32 rotation = 0.0f, IN BOOL flipH = false, IN BOOL flipV = false, IN Vec2 uvOffset = {});
STATIC VOID DrawSprite(IN Handle spriteSheet, IN INT32 animationIndex, IN INT32 frameIndex, IN Vec2 position,
IN Vec2 scale = {1.0f, 1.0f}, IN FLOAT32 rotation = 0.0f, IN BOOL flipH = false,
IN BOOL flipV = false, IN Vec2 uvOffset = {});
private: private:
STATIC VOID Initialize(); STATIC VOID Initialize();
@ -33,4 +58,4 @@ namespace ia::iae
friend INT32 Run(IN CONST String &name, IN CONST String &packageName, IN CONST String &developerName, friend INT32 Run(IN CONST String &name, IN CONST String &packageName, IN CONST String &developerName,
IN CONST String &publisherName, IN IA_VERSION_TYPE version); IN CONST String &publisherName, IN IA_VERSION_TYPE version);
}; };
} } // namespace ia::iae