First commit
This commit is contained in:
248
src/resource/anm2.cpp
Normal file
248
src/resource/anm2.cpp
Normal file
@@ -0,0 +1,248 @@
|
||||
#include "anm2.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace tinyxml2;
|
||||
using namespace game::resource;
|
||||
|
||||
namespace game::anm2
|
||||
{
|
||||
XMLError query_string_attribute(XMLElement* element, const char* attribute, std::string* value)
|
||||
{
|
||||
const char* temp = nullptr;
|
||||
auto result = element->QueryStringAttribute(attribute, &temp);
|
||||
if (result == XML_SUCCESS && temp && value) *value = temp;
|
||||
return result;
|
||||
}
|
||||
|
||||
XMLError query_path_attribute(XMLElement* element, const char* attribute, std::filesystem::path* value)
|
||||
{
|
||||
std::string temp{};
|
||||
auto result = query_string_attribute(element, attribute, &temp);
|
||||
if (value) *value = std::filesystem::path(temp);
|
||||
return result;
|
||||
}
|
||||
|
||||
XMLError query_color_attribute(XMLElement* element, const char* attribute, float* value)
|
||||
{
|
||||
int temp{};
|
||||
auto result = element->QueryIntAttribute(attribute, &temp);
|
||||
if (result == XML_SUCCESS && value) *value = (temp / 255.0f);
|
||||
return result;
|
||||
}
|
||||
|
||||
Info::Info(XMLElement* element)
|
||||
{
|
||||
if (!element) return;
|
||||
element->QueryIntAttribute("Fps", &fps);
|
||||
}
|
||||
|
||||
Spritesheet::Spritesheet(XMLElement* element, int& id, TextureCallback textureCallback)
|
||||
{
|
||||
if (!element) return;
|
||||
element->QueryIntAttribute("Id", &id);
|
||||
query_path_attribute(element, "Path", &path);
|
||||
texture = Texture(path);
|
||||
}
|
||||
|
||||
Layer::Layer(XMLElement* element, int& id)
|
||||
{
|
||||
if (!element) return;
|
||||
element->QueryIntAttribute("Id", &id);
|
||||
query_string_attribute(element, "Name", &name);
|
||||
element->QueryIntAttribute("SpritesheetId", &spritesheetID);
|
||||
}
|
||||
|
||||
Null::Null(XMLElement* element, int& id)
|
||||
{
|
||||
if (!element) return;
|
||||
element->QueryIntAttribute("Id", &id);
|
||||
query_string_attribute(element, "Name", &name);
|
||||
element->QueryBoolAttribute("ShowRect", &isShowRect);
|
||||
}
|
||||
|
||||
Event::Event(XMLElement* element, int& id)
|
||||
{
|
||||
if (!element) return;
|
||||
element->QueryIntAttribute("Id", &id);
|
||||
query_string_attribute(element, "Name", &name);
|
||||
}
|
||||
|
||||
Sound::Sound(XMLElement* element, int& id, SoundCallback soundCallback)
|
||||
{
|
||||
if (!element) return;
|
||||
element->QueryIntAttribute("Id", &id);
|
||||
query_path_attribute(element, "Path", &path);
|
||||
audio = Audio(path);
|
||||
}
|
||||
|
||||
Content::Content(XMLElement* element, TextureCallback textureCallback, SoundCallback soundCallback)
|
||||
{
|
||||
if (auto spritesheetsElement = element->FirstChildElement("Spritesheets"))
|
||||
{
|
||||
for (auto child = spritesheetsElement->FirstChildElement("Spritesheet"); child;
|
||||
child = child->NextSiblingElement("Spritesheet"))
|
||||
{
|
||||
int spritesheetId{};
|
||||
Spritesheet spritesheet(child, spritesheetId, textureCallback);
|
||||
spritesheets.emplace(spritesheetId, std::move(spritesheet));
|
||||
}
|
||||
}
|
||||
|
||||
if (auto layersElement = element->FirstChildElement("Layers"))
|
||||
{
|
||||
for (auto child = layersElement->FirstChildElement("Layer"); child; child = child->NextSiblingElement("Layer"))
|
||||
{
|
||||
int layerId{};
|
||||
Layer layer(child, layerId);
|
||||
layers.emplace(layerId, std::move(layer));
|
||||
}
|
||||
}
|
||||
|
||||
if (auto nullsElement = element->FirstChildElement("Nulls"))
|
||||
{
|
||||
for (auto child = nullsElement->FirstChildElement("Null"); child; child = child->NextSiblingElement("Null"))
|
||||
{
|
||||
int nullId{};
|
||||
Null null(child, nullId);
|
||||
nulls.emplace(nullId, std::move(null));
|
||||
}
|
||||
}
|
||||
|
||||
if (auto eventsElement = element->FirstChildElement("Events"))
|
||||
{
|
||||
for (auto child = eventsElement->FirstChildElement("Event"); child; child = child->NextSiblingElement("Event"))
|
||||
{
|
||||
int eventId{};
|
||||
Event event(child, eventId);
|
||||
events.emplace(eventId, std::move(event));
|
||||
}
|
||||
}
|
||||
|
||||
if (auto soundsElement = element->FirstChildElement("Sounds"))
|
||||
{
|
||||
for (auto child = soundsElement->FirstChildElement("Sound"); child; child = child->NextSiblingElement("Sound"))
|
||||
{
|
||||
int soundId{};
|
||||
Sound sound(child, soundId, soundCallback);
|
||||
sounds.emplace(soundId, std::move(sound));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Frame::Frame(XMLElement* element, Type type)
|
||||
{
|
||||
if (type != TRIGGER)
|
||||
{
|
||||
element->QueryFloatAttribute("XPosition", &position.x);
|
||||
element->QueryFloatAttribute("YPosition", &position.y);
|
||||
if (type == LAYER)
|
||||
{
|
||||
element->QueryFloatAttribute("XPivot", &pivot.x);
|
||||
element->QueryFloatAttribute("YPivot", &pivot.y);
|
||||
element->QueryFloatAttribute("XCrop", &crop.x);
|
||||
element->QueryFloatAttribute("YCrop", &crop.y);
|
||||
element->QueryFloatAttribute("Width", &size.x);
|
||||
element->QueryFloatAttribute("Height", &size.y);
|
||||
}
|
||||
element->QueryFloatAttribute("XScale", &scale.x);
|
||||
element->QueryFloatAttribute("YScale", &scale.y);
|
||||
element->QueryIntAttribute("Delay", &duration);
|
||||
element->QueryBoolAttribute("Visible", &isVisible);
|
||||
query_color_attribute(element, "RedTint", &tint.r);
|
||||
query_color_attribute(element, "GreenTint", &tint.g);
|
||||
query_color_attribute(element, "BlueTint", &tint.b);
|
||||
query_color_attribute(element, "AlphaTint", &tint.a);
|
||||
query_color_attribute(element, "RedOffset", &colorOffset.r);
|
||||
query_color_attribute(element, "GreenOffset", &colorOffset.g);
|
||||
query_color_attribute(element, "BlueOffset", &colorOffset.b);
|
||||
element->QueryFloatAttribute("Rotation", &rotation);
|
||||
element->QueryBoolAttribute("Interpolated", &isInterpolated);
|
||||
}
|
||||
else
|
||||
{
|
||||
element->QueryIntAttribute("EventId", &eventID);
|
||||
element->QueryIntAttribute("SoundId", &soundID);
|
||||
element->QueryIntAttribute("AtFrame", &atFrame);
|
||||
}
|
||||
}
|
||||
|
||||
Item::Item(XMLElement* element, Type type, int& id)
|
||||
{
|
||||
if (type == LAYER) element->QueryIntAttribute("LayerId", &id);
|
||||
if (type == NULL_) element->QueryIntAttribute("NullId", &id);
|
||||
|
||||
element->QueryBoolAttribute("Visible", &isVisible);
|
||||
|
||||
for (auto child = type == TRIGGER ? element->FirstChildElement("Trigger") : element->FirstChildElement("Frame");
|
||||
child; child = type == TRIGGER ? child->NextSiblingElement("Trigger") : child->NextSiblingElement("Frame"))
|
||||
frames.emplace_back(Frame(child, type));
|
||||
}
|
||||
|
||||
Animation::Animation(XMLElement* element)
|
||||
{
|
||||
query_string_attribute(element, "Name", &name);
|
||||
element->QueryIntAttribute("FrameNum", &frameNum);
|
||||
element->QueryBoolAttribute("Loop", &isLoop);
|
||||
|
||||
int id{-1};
|
||||
|
||||
if (auto rootAnimationElement = element->FirstChildElement("RootAnimation"))
|
||||
rootAnimation = Item(rootAnimationElement, ROOT, id);
|
||||
|
||||
if (auto layerAnimationsElement = element->FirstChildElement("LayerAnimations"))
|
||||
{
|
||||
for (auto child = layerAnimationsElement->FirstChildElement("LayerAnimation"); child;
|
||||
child = child->NextSiblingElement("LayerAnimation"))
|
||||
{
|
||||
Item layerAnimation(child, LAYER, id);
|
||||
layerOrder.push_back(id);
|
||||
layerAnimations.emplace(id, std::move(layerAnimation));
|
||||
}
|
||||
}
|
||||
|
||||
if (auto nullAnimationsElement = element->FirstChildElement("NullAnimations"))
|
||||
{
|
||||
for (auto child = nullAnimationsElement->FirstChildElement("NullAnimation"); child;
|
||||
child = child->NextSiblingElement("NullAnimation"))
|
||||
{
|
||||
Item nullAnimation(child, NULL_, id);
|
||||
nullAnimations.emplace(id, std::move(nullAnimation));
|
||||
}
|
||||
}
|
||||
|
||||
if (auto triggersElement = element->FirstChildElement("Triggers")) triggers = Item(triggersElement, TRIGGER, id);
|
||||
}
|
||||
|
||||
Animations::Animations(XMLElement* element)
|
||||
{
|
||||
query_string_attribute(element, "DefaultAnimation", &defaultAnimation);
|
||||
|
||||
for (auto child = element->FirstChildElement("Animation"); child; child = child->NextSiblingElement("Animation"))
|
||||
items.emplace_back(Animation(child));
|
||||
}
|
||||
|
||||
Anm2::Anm2(const std::filesystem::path& path, TextureCallback textureCallback, SoundCallback soundCallback)
|
||||
{
|
||||
XMLDocument document;
|
||||
|
||||
if (document.LoadFile(path.c_str()) != XML_SUCCESS)
|
||||
{
|
||||
std::cout << "Failed to initialize anm2: " << document.ErrorStr() << "\n";
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "Initialzed anm2: " << path.string() << "\n";
|
||||
|
||||
auto previousPath = std::filesystem::current_path();
|
||||
std::filesystem::current_path(path.parent_path());
|
||||
|
||||
auto element = document.RootElement();
|
||||
|
||||
if (auto infoElement = element->FirstChildElement("Info")) info = Info(infoElement);
|
||||
if (auto contentElement = element->FirstChildElement("Content"))
|
||||
content = Content(contentElement, textureCallback, soundCallback);
|
||||
if (auto animationsElement = element->FirstChildElement("Animations")) animations = Animations(animationsElement);
|
||||
|
||||
std::filesystem::current_path(previousPath);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user