it's kind of finished
This commit is contained in:
24
src/COMMON.h
24
src/COMMON.h
@@ -108,17 +108,35 @@ static inline s32 map_next_id_get(const std::map<s32, T>& map) {
|
|||||||
s32 id = 0; for (const auto& [key, _] : map) if (key != id) break; else ++id; return id;
|
s32 id = 0; for (const auto& [key, _] : map) if (key != id) break; else ++id; return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Swaps elements in a map */
|
||||||
|
/* If neither key exists, do nothing */
|
||||||
|
/* If one key exists, change its ID */
|
||||||
|
/* If both keys exist, swap */
|
||||||
template<typename Map, typename Key>
|
template<typename Map, typename Key>
|
||||||
static inline void map_swap(Map& map, const Key& key1, const Key& key2)
|
static inline void map_swap(Map& map, const Key& key1, const Key& key2)
|
||||||
{
|
{
|
||||||
auto it1 = map.find(key1);
|
if (key1 == key2)
|
||||||
auto it2 = map.find(key2);
|
|
||||||
if (it1 == map.end() || it2 == map.end())
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
auto it1 = map.find(key1);
|
||||||
|
auto it2 = map.find(key2);
|
||||||
|
|
||||||
|
if (it1 != map.end() && it2 != map.end())
|
||||||
|
{
|
||||||
using std::swap;
|
using std::swap;
|
||||||
swap(it1->second, it2->second);
|
swap(it1->second, it2->second);
|
||||||
}
|
}
|
||||||
|
else if (it1 != map.end())
|
||||||
|
{
|
||||||
|
map[key2] = std::move(it1->second);
|
||||||
|
map.erase(it1);
|
||||||
|
}
|
||||||
|
else if (it2 != map.end())
|
||||||
|
{
|
||||||
|
map[key1] = std::move(it2->second);
|
||||||
|
map.erase(it2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#define DEFINE_ENUM_TO_STRING_FN(fn_name, arr, count) \
|
#define DEFINE_ENUM_TO_STRING_FN(fn_name, arr, count) \
|
||||||
static inline const char* fn_name(s32 index) { \
|
static inline const char* fn_name(s32 index) { \
|
||||||
|
@@ -62,13 +62,15 @@
|
|||||||
#define STRING_IMGUI_ANIMATIONS_REMOVE "Remove"
|
#define STRING_IMGUI_ANIMATIONS_REMOVE "Remove"
|
||||||
#define STRING_IMGUI_ANIMATIONS_DUPLICATE "Duplicate"
|
#define STRING_IMGUI_ANIMATIONS_DUPLICATE "Duplicate"
|
||||||
#define STRING_IMGUI_ANIMATIONS_SET_AS_DEFAULT "Set as Default"
|
#define STRING_IMGUI_ANIMATIONS_SET_AS_DEFAULT "Set as Default"
|
||||||
#define STRING_IMGUI_ANIMATIONS_DEFAULT_ANIMATION_FORMAT "%s (*)"
|
#define STRING_IMGUI_ANIMATIONS_DEFAULT_ANIMATION_FORMAT "(*) %s "
|
||||||
|
#define STRING_IMGUI_ANIMATIONS_DRAG_DROP "Animation Drag/Drop"
|
||||||
|
|
||||||
#define STRING_IMGUI_EVENTS "Events"
|
#define STRING_IMGUI_EVENTS "Events"
|
||||||
#define STRING_IMGUI_EVENTS_EVENT_LABEL "##Event"
|
#define STRING_IMGUI_EVENTS_EVENT_LABEL "##Event"
|
||||||
#define STRING_IMGUI_EVENTS_ADD "Add"
|
#define STRING_IMGUI_EVENTS_ADD "Add"
|
||||||
#define STRING_IMGUI_EVENTS_REMOVE "Remove"
|
#define STRING_IMGUI_EVENTS_REMOVE "Remove"
|
||||||
#define STRING_IMGUI_EVENT_FORMAT "#%i %s"
|
#define STRING_IMGUI_EVENT_FORMAT "#%i %s"
|
||||||
|
#define STRING_IMGUI_EVENTS_DRAG_DROP "Event Drag/Drop"
|
||||||
|
|
||||||
#define STRING_IMGUI_SPRITESHEETS "Spritesheets"
|
#define STRING_IMGUI_SPRITESHEETS "Spritesheets"
|
||||||
#define STRING_IMGUI_SPRITESHEETS_ADD "Add"
|
#define STRING_IMGUI_SPRITESHEETS_ADD "Add"
|
||||||
@@ -76,6 +78,7 @@
|
|||||||
#define STRING_IMGUI_SPRITESHEETS_RELOAD "Reload"
|
#define STRING_IMGUI_SPRITESHEETS_RELOAD "Reload"
|
||||||
#define STRING_IMGUI_SPRITESHEETS_REPLACE "Replace"
|
#define STRING_IMGUI_SPRITESHEETS_REPLACE "Replace"
|
||||||
#define STRING_IMGUI_SPRITESHEET_FORMAT "#%i %s"
|
#define STRING_IMGUI_SPRITESHEET_FORMAT "#%i %s"
|
||||||
|
#define STRING_IMGUI_SPRITESHEETS_DRAG_DROP "Spritesheet Drag/Drop"
|
||||||
|
|
||||||
#define STRING_IMGUI_FRAME_PROPERTIES "Frame Properties"
|
#define STRING_IMGUI_FRAME_PROPERTIES "Frame Properties"
|
||||||
#define STRING_IMGUI_FRAME_PROPERTIES_CROP_POSITION "Crop Position"
|
#define STRING_IMGUI_FRAME_PROPERTIES_CROP_POSITION "Crop Position"
|
||||||
@@ -116,12 +119,15 @@
|
|||||||
#define STRING_IMGUI_ANIMATION_PREVIEW_AXIS_COLOR "Color"
|
#define STRING_IMGUI_ANIMATION_PREVIEW_AXIS_COLOR "Color"
|
||||||
#define STRING_IMGUI_ANIMATION_PREVIEW_ROOT_TRANSFORM "Root Transform"
|
#define STRING_IMGUI_ANIMATION_PREVIEW_ROOT_TRANSFORM "Root Transform"
|
||||||
#define STRING_IMGUI_ANIMATION_PREVIEW_SHOW_PIVOT "Show Pivot"
|
#define STRING_IMGUI_ANIMATION_PREVIEW_SHOW_PIVOT "Show Pivot"
|
||||||
|
#define STRING_IMGUI_ANIMATION_PREVIEW_POSITION "##Position"
|
||||||
|
#define STRING_IMGUI_ANIMATION_PREVIEW_POSITION_FORMAT "Position: {%5.0f, %5.0f}"
|
||||||
|
|
||||||
#define STRING_IMGUI_SPRITESHEET_EDITOR "Spritesheet Editor"
|
#define STRING_IMGUI_SPRITESHEET_EDITOR "Spritesheet Editor"
|
||||||
#define STRING_IMGUI_SPRITESHEET_EDITOR_LABEL "##Animation Preview"
|
#define STRING_IMGUI_SPRITESHEET_EDITOR_LABEL "##Animation Preview"
|
||||||
#define STRING_IMGUI_SPRITESHEET_EDITOR_SETTINGS "##Animation Preview Settings"
|
#define STRING_IMGUI_SPRITESHEET_EDITOR_SETTINGS "##Animation Preview Settings"
|
||||||
#define STRING_IMGUI_SPRITESHEET_EDITOR_GRID_SETTINGS "##Grid Settings"
|
#define STRING_IMGUI_SPRITESHEET_EDITOR_GRID_SETTINGS "##Grid Settings"
|
||||||
#define STRING_IMGUI_SPRITESHEET_EDITOR_GRID "Grid"
|
#define STRING_IMGUI_SPRITESHEET_EDITOR_GRID "Grid"
|
||||||
|
#define STRING_IMGUI_SPRITESHEET_EDITOR_GRID_SNAP "Snap"
|
||||||
#define STRING_IMGUI_SPRITESHEET_EDITOR_GRID_SIZE "Size"
|
#define STRING_IMGUI_SPRITESHEET_EDITOR_GRID_SIZE "Size"
|
||||||
#define STRING_IMGUI_SPRITESHEET_EDITOR_GRID_OFFSET "Offset"
|
#define STRING_IMGUI_SPRITESHEET_EDITOR_GRID_OFFSET "Offset"
|
||||||
#define STRING_IMGUI_SPRITESHEET_EDITOR_GRID_COLOR "Color"
|
#define STRING_IMGUI_SPRITESHEET_EDITOR_GRID_COLOR "Color"
|
||||||
@@ -131,6 +137,8 @@
|
|||||||
#define STRING_IMGUI_SPRITESHEET_EDITOR_BACKGROUND_COLOR "Background Color"
|
#define STRING_IMGUI_SPRITESHEET_EDITOR_BACKGROUND_COLOR "Background Color"
|
||||||
#define STRING_IMGUI_SPRITESHEET_EDITOR_CENTER_VIEW "Center View"
|
#define STRING_IMGUI_SPRITESHEET_EDITOR_CENTER_VIEW "Center View"
|
||||||
#define STRING_IMGUI_SPRITESHEET_EDITOR_BORDER "Border"
|
#define STRING_IMGUI_SPRITESHEET_EDITOR_BORDER "Border"
|
||||||
|
#define STRING_IMGUI_SPRITESHEET_EDITOR_POSITION "##Position"
|
||||||
|
#define STRING_IMGUI_SPRITESHEET_EDITOR_POSITION_FORMAT "Position: {%5.0f, %5.0f}"
|
||||||
|
|
||||||
#define STRING_IMGUI_TIMELINE "Timeline"
|
#define STRING_IMGUI_TIMELINE "Timeline"
|
||||||
#define STRING_IMGUI_TIMELINE_HEADER "##Header"
|
#define STRING_IMGUI_TIMELINE_HEADER "##Header"
|
||||||
@@ -178,6 +186,8 @@
|
|||||||
#define STRING_IMGUI_TIMELINE_VIEWER "Viewer"
|
#define STRING_IMGUI_TIMELINE_VIEWER "Viewer"
|
||||||
#define STRING_IMGUI_TIMELINE_CHILD "Timeline"
|
#define STRING_IMGUI_TIMELINE_CHILD "Timeline"
|
||||||
#define STRING_IMGUI_TIMELINE_MAIN "Main"
|
#define STRING_IMGUI_TIMELINE_MAIN "Main"
|
||||||
|
#define STRING_IMGUI_TIMELINE_FRAME_DRAG_DROP "Frame Drag/Drop"
|
||||||
|
#define STRING_IMGUI_TIMELINE_ITEM_DRAG_DROP "Item Drag/Drop"
|
||||||
|
|
||||||
#define STRING_IMGUI_TOOLS "Tools"
|
#define STRING_IMGUI_TOOLS "Tools"
|
||||||
#define STRING_IMGUI_TOOLS_PAN "##Pan"
|
#define STRING_IMGUI_TOOLS_PAN "##Pan"
|
||||||
@@ -190,7 +200,7 @@
|
|||||||
#define STRING_IMGUI_TOOLTIP_ANIMATIONS_DUPLICATE "Duplicates the selected animation."
|
#define STRING_IMGUI_TOOLTIP_ANIMATIONS_DUPLICATE "Duplicates the selected animation."
|
||||||
#define STRING_IMGUI_TOOLTIP_ANIMATIONS_REMOVE "Removes the selected animation."
|
#define STRING_IMGUI_TOOLTIP_ANIMATIONS_REMOVE "Removes the selected animation."
|
||||||
#define STRING_IMGUI_TOOLTIP_ANIMATIONS_SELECT "Select the animation to edit.\nYou can also click the name to edit it."
|
#define STRING_IMGUI_TOOLTIP_ANIMATIONS_SELECT "Select the animation to edit.\nYou can also click the name to edit it."
|
||||||
#define STRING_IMGUI_TOOLTIP_ANIMATIONS_SET_AS_DEFAULT "Sets the selected animation as the default.\nDefault animations are marked with \"(*)\"."
|
#define STRING_IMGUI_TOOLTIP_ANIMATIONS_SET_AS_DEFAULT "Sets the selected animation as the default.\nThe default animation is marked with \"(*)\"."
|
||||||
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_AXIS "Toggles the display of the X/Y axes on the animation preview."
|
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_AXIS "Toggles the display of the X/Y axes on the animation preview."
|
||||||
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_AXIS_COLOR "Changes the color of the X/Y axes on the animation preview."
|
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_AXIS_COLOR "Changes the color of the X/Y axes on the animation preview."
|
||||||
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_BACKGROUND_COLOR "Changes the background color of the animation preview."
|
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_BACKGROUND_COLOR "Changes the background color of the animation preview."
|
||||||
@@ -200,7 +210,7 @@
|
|||||||
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_GRID_OFFSET "Changes the animation preview grid's offset, in pixels."
|
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_GRID_OFFSET "Changes the animation preview grid's offset, in pixels."
|
||||||
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_GRID_SIZE "Changes the animation preview grid's size, in pixels."
|
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_GRID_SIZE "Changes the animation preview grid's size, in pixels."
|
||||||
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_ZOOM "Changes the animation preview zoom level."
|
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_ZOOM "Changes the animation preview zoom level."
|
||||||
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_ROOT_TRANSFORM "Toggle the properties of the Root element of an animation being able to change the properties (such as position or scale) of all of the animation's elements."
|
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_ROOT_TRANSFORM "Toggle the properties of the Root element of an animation being able to change the properties (such as position or scale) of all of the animation's elements.\nNOTE: Scale/rotation currently not implemented. Matrix math is hard."
|
||||||
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_SHOW_PIVOT "Toggle the pivots of layer animation elements being visible on the animation preview."
|
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_SHOW_PIVOT "Toggle the pivots of layer animation elements being visible on the animation preview."
|
||||||
#define STRING_IMGUI_TOOLTIP_EVENTS_ADD "Add a new event."
|
#define STRING_IMGUI_TOOLTIP_EVENTS_ADD "Add a new event."
|
||||||
#define STRING_IMGUI_TOOLTIP_EVENTS_REMOVE "Removes the selected event."
|
#define STRING_IMGUI_TOOLTIP_EVENTS_REMOVE "Removes the selected event."
|
||||||
@@ -251,16 +261,17 @@
|
|||||||
#define STRING_IMGUI_TOOLTIP_SPRITESHEET_EDITOR_BACKGROUND_COLOR "Changes the background color of the spritesheet editor."
|
#define STRING_IMGUI_TOOLTIP_SPRITESHEET_EDITOR_BACKGROUND_COLOR "Changes the background color of the spritesheet editor."
|
||||||
#define STRING_IMGUI_TOOLTIP_SPRITESHEET_EDITOR_CENTER_VIEW "Centers the spritesheet editor's pan."
|
#define STRING_IMGUI_TOOLTIP_SPRITESHEET_EDITOR_CENTER_VIEW "Centers the spritesheet editor's pan."
|
||||||
#define STRING_IMGUI_TOOLTIP_SPRITESHEET_EDITOR_GRID "Toggles grid visibility on the spritesheet editor."
|
#define STRING_IMGUI_TOOLTIP_SPRITESHEET_EDITOR_GRID "Toggles grid visibility on the spritesheet editor."
|
||||||
|
#define STRING_IMGUI_TOOLTIP_SPRITESHEET_EDITOR_GRID_SNAP "When using the crop tool, will snap points to the grid."
|
||||||
#define STRING_IMGUI_TOOLTIP_SPRITESHEET_EDITOR_GRID_COLOR "Changes the spritesheet editor grid color."
|
#define STRING_IMGUI_TOOLTIP_SPRITESHEET_EDITOR_GRID_COLOR "Changes the spritesheet editor grid color."
|
||||||
#define STRING_IMGUI_TOOLTIP_SPRITESHEET_EDITOR_GRID_OFFSET "Changes the spritesheet editor grid's offset, in pixels."
|
#define STRING_IMGUI_TOOLTIP_SPRITESHEET_EDITOR_GRID_OFFSET "Changes the spritesheet editor grid's offset, in pixels."
|
||||||
#define STRING_IMGUI_TOOLTIP_SPRITESHEET_EDITOR_GRID_SIZE "Changes the spritesheet editor grid's size, in pixels."
|
#define STRING_IMGUI_TOOLTIP_SPRITESHEET_EDITOR_GRID_SIZE "Changes the spritesheet editor grid's size, in pixels."
|
||||||
#define STRING_IMGUI_TOOLTIP_SPRITESHEET_EDITOR_ZOOM "Changes the spritesheet editor zoom level."
|
#define STRING_IMGUI_TOOLTIP_SPRITESHEET_EDITOR_ZOOM "Changes the spritesheet editor zoom level."
|
||||||
#define STRING_IMGUI_TOOLTIP_SPRITESHEET_EDITOR_BORDER "Toggles a border appearing around the confines of the spritesheet."
|
#define STRING_IMGUI_TOOLTIP_SPRITESHEET_EDITOR_BORDER "Toggles a border appearing around the confines of the spritesheet."
|
||||||
#define STRING_IMGUI_TOOLTIP_TOOLS_PAN "Use the pan tool.\nWill shift the view as the cursor is dragged."
|
#define STRING_IMGUI_TOOLTIP_TOOLS_PAN "Use the pan tool.\nWill shift the view as the cursor is dragged."
|
||||||
#define STRING_IMGUI_TOOLTIP_TOOLS_MOVE "Use the move tool.\nWill move selected elements as the cursor is dragged."
|
#define STRING_IMGUI_TOOLTIP_TOOLS_MOVE "Use the move tool.\nWill move selected elements as the cursor is dragged.\n(Animation Preview only.)"
|
||||||
#define STRING_IMGUI_TOOLTIP_TOOLS_ROTATE "Use the rotate tool.\nWill rotate selected elements as the cursor is dragged."
|
#define STRING_IMGUI_TOOLTIP_TOOLS_ROTATE "Use the rotate tool.\nWill rotate selected elements as the cursor is dragged.\n(Animation Preview only.)"
|
||||||
#define STRING_IMGUI_TOOLTIP_TOOLS_SCALE "Use the scale tool.\nWill scale the selected elements as the cursor is dragged."
|
#define STRING_IMGUI_TOOLTIP_TOOLS_SCALE "Use the scale tool.\nWill scale the selected elements as the cursor is dragged.\n(Animation Preview only.)"
|
||||||
#define STRING_IMGUI_TOOLTIP_TOOLS_CROP "Use the crop tool.\nWill set the crop of the selected elements as the cursor is dragged."
|
#define STRING_IMGUI_TOOLTIP_TOOLS_CROP "Use the crop tool.\nWill set the crop of the selected elements as the cursor is dragged.\n(Spritesheet Editor only.)"
|
||||||
|
|
||||||
#define STRING_OPENGL_VERSION "#version 330"
|
#define STRING_OPENGL_VERSION "#version 330"
|
||||||
|
|
||||||
|
480
src/anm2.cpp
480
src/anm2.cpp
@@ -37,7 +37,6 @@ anm2_serialize(Anm2* self, const char* path)
|
|||||||
if (!self || !path)
|
if (!self || !path)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
||||||
/* Update creation date on first version */
|
/* Update creation date on first version */
|
||||||
if (self->version == 0)
|
if (self->version == 0)
|
||||||
anm2_created_on_set(self);
|
anm2_created_on_set(self);
|
||||||
@@ -45,8 +44,6 @@ anm2_serialize(Anm2* self, const char* path)
|
|||||||
/* Increment anm2's version */
|
/* Increment anm2's version */
|
||||||
self->version++;
|
self->version++;
|
||||||
|
|
||||||
/* Set the anm2's date to the system time */
|
|
||||||
|
|
||||||
/* AnimatedActor */
|
/* AnimatedActor */
|
||||||
animatedActorElement = document.NewElement(ANM2_ELEMENT_STRINGS[ANM2_ELEMENT_ANIMATED_ACTOR]);
|
animatedActorElement = document.NewElement(ANM2_ELEMENT_STRINGS[ANM2_ELEMENT_ANIMATED_ACTOR]);
|
||||||
document.InsertFirstChild(animatedActorElement);
|
document.InsertFirstChild(animatedActorElement);
|
||||||
@@ -283,14 +280,14 @@ anm2_serialize(Anm2* self, const char* path)
|
|||||||
/* Triggers */
|
/* Triggers */
|
||||||
triggersElement = document.NewElement(ANM2_ELEMENT_STRINGS[ANM2_ELEMENT_TRIGGERS]);
|
triggersElement = document.NewElement(ANM2_ELEMENT_STRINGS[ANM2_ELEMENT_TRIGGERS]);
|
||||||
|
|
||||||
for (auto & trigger : animation.triggers.items)
|
for (auto & frame : animation.triggers.frames)
|
||||||
{
|
{
|
||||||
XMLElement* triggerElement;
|
XMLElement* triggerElement;
|
||||||
|
|
||||||
/* Trigger */
|
/* Trigger */
|
||||||
triggerElement = document.NewElement(ANM2_ELEMENT_STRINGS[ANM2_ELEMENT_TRIGGER]);
|
triggerElement = document.NewElement(ANM2_ELEMENT_STRINGS[ANM2_ELEMENT_TRIGGER]);
|
||||||
triggerElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_EVENT_ID], trigger.eventID); /* EventID */
|
triggerElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_EVENT_ID], frame.eventID); /* EventID */
|
||||||
triggerElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_AT_FRAME], trigger.atFrame); /* AtFrame */
|
triggerElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_AT_FRAME], frame.atFrame); /* AtFrame */
|
||||||
triggersElement->InsertEndChild(triggerElement);
|
triggersElement->InsertEndChild(triggerElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,35 +318,27 @@ anm2_serialize(Anm2* self, const char* path)
|
|||||||
bool
|
bool
|
||||||
anm2_deserialize(Anm2* self, Resources* resources, const char* path)
|
anm2_deserialize(Anm2* self, Resources* resources, const char* path)
|
||||||
{
|
{
|
||||||
XMLDocument document;
|
XMLDocument xmlDocument;
|
||||||
XMLError error;
|
XMLError xmlError;
|
||||||
const XMLElement* element;
|
const XMLElement* xmlElement;
|
||||||
const XMLElement* root;
|
const XMLElement* xmlRoot;
|
||||||
Anm2Spritesheet* lastSpritesheet = NULL;
|
Anm2Animation* animation = NULL;
|
||||||
Anm2Layer* lastLayer = NULL;
|
Anm2Layer* layer = NULL;
|
||||||
Anm2Null* lastNull = NULL;
|
Anm2Null* null = NULL;
|
||||||
Anm2Event* lastEvent = NULL;
|
Anm2Item* item = NULL;
|
||||||
Anm2Animation* lastAnimation = NULL;
|
Anm2Event* event = NULL;
|
||||||
Anm2LayerAnimation* lastLayerAnimation = NULL;
|
Anm2Frame* frame = NULL;
|
||||||
Anm2NullAnimation* lastNullAnimation = NULL;
|
Anm2Spritesheet* spritesheet = NULL;
|
||||||
Anm2Frame* lastFrame = NULL;
|
|
||||||
Anm2Trigger* lastTrigger = NULL;
|
|
||||||
Anm2Element anm2Element = ANM2_ELEMENT_ANIMATED_ACTOR;
|
Anm2Element anm2Element = ANM2_ELEMENT_ANIMATED_ACTOR;
|
||||||
Anm2Attribute anm2Attribute = ANM2_ATTRIBUTE_ID;
|
Anm2Attribute anm2Attribute = ANM2_ATTRIBUTE_ID;
|
||||||
Anm2AnimationType animationType = ANM2_ROOT_ANIMATION;
|
|
||||||
Anm2Null tempNull;
|
|
||||||
Anm2Layer tempLayer;
|
|
||||||
Anm2Spritesheet tempSpritesheet;
|
|
||||||
Anm2Event tempEvent;
|
|
||||||
char lastSpritesheetPath[PATH_MAX];
|
|
||||||
|
|
||||||
*self = Anm2{};
|
*self = Anm2{};
|
||||||
|
|
||||||
error = document.LoadFile(path);
|
xmlError = xmlDocument.LoadFile(path);
|
||||||
|
|
||||||
if (error != XML_SUCCESS)
|
if (xmlError != XML_SUCCESS)
|
||||||
{
|
{
|
||||||
printf(STRING_ERROR_ANM2_READ, path, document.ErrorStr());
|
printf(STRING_ERROR_ANM2_READ, path, xmlDocument.ErrorStr());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,297 +346,252 @@ anm2_deserialize(Anm2* self, Resources* resources, const char* path)
|
|||||||
strncpy(self->path, path, PATH_MAX - 1);
|
strncpy(self->path, path, PATH_MAX - 1);
|
||||||
working_directory_from_path_set(path);
|
working_directory_from_path_set(path);
|
||||||
|
|
||||||
root = document.FirstChildElement(ANM2_ELEMENT_STRINGS[ANM2_ELEMENT_ANIMATED_ACTOR]);
|
xmlRoot = xmlDocument.FirstChildElement(ANM2_ELEMENT_STRINGS[ANM2_ELEMENT_ANIMATED_ACTOR]);
|
||||||
element = root;
|
xmlElement = xmlRoot;
|
||||||
|
|
||||||
while (element)
|
while (xmlElement)
|
||||||
{
|
{
|
||||||
const XMLAttribute* attribute;
|
|
||||||
const XMLElement* child;
|
const XMLAttribute* xmlAttribute = NULL;
|
||||||
s32 id;
|
const XMLElement* xmlChild = NULL;
|
||||||
|
s32 id = 0;
|
||||||
|
|
||||||
/* Elements */
|
/* Elements */
|
||||||
anm2Element = anm2_element_from_string(element->Name());
|
anm2Element = anm2_element_from_string(xmlElement->Name());
|
||||||
|
|
||||||
switch (anm2Element)
|
switch (anm2Element)
|
||||||
{
|
{
|
||||||
case ANM2_ELEMENT_SPRITESHEET:
|
case ANM2_ELEMENT_SPRITESHEET:
|
||||||
lastSpritesheet = &tempSpritesheet;
|
id = map_next_id_get(self->spritesheets);
|
||||||
|
self->spritesheets[id] = Anm2Spritesheet{};
|
||||||
|
spritesheet = &self->spritesheets[id];
|
||||||
break;
|
break;
|
||||||
case ANM2_ELEMENT_LAYER:
|
case ANM2_ELEMENT_LAYER:
|
||||||
lastLayer = &tempLayer;
|
id = map_next_id_get(self->layers);
|
||||||
|
self->layers[id] = Anm2Layer{};
|
||||||
|
layer = &self->layers[id];
|
||||||
break;
|
break;
|
||||||
case ANM2_ELEMENT_NULL:
|
case ANM2_ELEMENT_NULL:
|
||||||
lastNull = &tempNull;
|
id = map_next_id_get(self->nulls);
|
||||||
|
self->nulls[id] = Anm2Null{};
|
||||||
|
null = &self->nulls[id];
|
||||||
break;
|
break;
|
||||||
case ANM2_ELEMENT_EVENT:
|
case ANM2_ELEMENT_EVENT:
|
||||||
lastEvent = &tempEvent;
|
id = map_next_id_get(self->events);
|
||||||
|
self->events[id] = Anm2Event{};
|
||||||
|
event = &self->events[id];
|
||||||
break;
|
break;
|
||||||
case ANM2_ELEMENT_ANIMATION:
|
case ANM2_ELEMENT_ANIMATION:
|
||||||
id = map_next_id_get(self->animations);
|
id = map_next_id_get(self->animations);
|
||||||
self->animations[id] = Anm2Animation{};
|
self->animations[id] = Anm2Animation{};
|
||||||
lastAnimation = &self->animations[id];
|
animation = &self->animations[id];
|
||||||
break;
|
break;
|
||||||
case ANM2_ELEMENT_ROOT_ANIMATION:
|
case ANM2_ELEMENT_ROOT_ANIMATION:
|
||||||
animationType = ANM2_ROOT_ANIMATION;
|
item = &animation->rootAnimation;
|
||||||
break;
|
break;
|
||||||
case ANM2_ELEMENT_LAYER_ANIMATION:
|
case ANM2_ELEMENT_LAYER_ANIMATION:
|
||||||
animationType = ANM2_LAYER_ANIMATION;
|
id = map_next_id_get(animation->layerAnimations);
|
||||||
lastLayerAnimation = NULL;
|
animation->layerAnimations[id] = Anm2Item{};
|
||||||
|
item = &animation->layerAnimations[id];
|
||||||
break;
|
break;
|
||||||
case ANM2_ELEMENT_NULL_ANIMATION:
|
case ANM2_ELEMENT_NULL_ANIMATION:
|
||||||
animationType = ANM2_NULL_ANIMATION;
|
id = map_next_id_get(animation->nullAnimations);
|
||||||
lastNullAnimation = NULL;
|
animation->nullAnimations[id] = Anm2Item{};
|
||||||
|
item = &animation->nullAnimations[id];
|
||||||
|
break;
|
||||||
|
case ANM2_ELEMENT_TRIGGERS:
|
||||||
|
item = &animation->triggers;
|
||||||
break;
|
break;
|
||||||
case ANM2_ELEMENT_FRAME:
|
case ANM2_ELEMENT_FRAME:
|
||||||
switch (animationType)
|
|
||||||
{
|
|
||||||
case ANM2_ROOT_ANIMATION:
|
|
||||||
lastAnimation->rootAnimation.frames.push_back(Anm2Frame{});
|
|
||||||
lastFrame = &lastAnimation->rootAnimation.frames.back();
|
|
||||||
break;
|
|
||||||
case ANM2_LAYER_ANIMATION:
|
|
||||||
if (!lastLayerAnimation) break;
|
|
||||||
lastLayerAnimation->frames.push_back(Anm2Frame{});
|
|
||||||
lastFrame = &lastLayerAnimation->frames.back();
|
|
||||||
break;
|
|
||||||
case ANM2_NULL_ANIMATION:
|
|
||||||
if (!lastNullAnimation) break;
|
|
||||||
lastNullAnimation->frames.push_back(Anm2Frame{});
|
|
||||||
lastFrame = &lastNullAnimation->frames.back();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ANM2_ELEMENT_TRIGGER:
|
case ANM2_ELEMENT_TRIGGER:
|
||||||
lastAnimation->triggers.items.push_back(Anm2Trigger{});
|
item->frames.push_back(Anm2Frame{});
|
||||||
lastTrigger = &lastAnimation->triggers.items.back();
|
frame = &item->frames.back();
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Attributes */
|
/* Attributes */
|
||||||
attribute = element->FirstAttribute();
|
xmlAttribute = xmlElement->FirstAttribute();
|
||||||
|
|
||||||
while (attribute)
|
while (xmlAttribute)
|
||||||
{
|
{
|
||||||
anm2Attribute = anm2_attribute_from_string(attribute->Name());
|
anm2Attribute = anm2_attribute_from_string(xmlAttribute->Name());
|
||||||
|
|
||||||
switch (anm2Attribute)
|
switch (anm2Attribute)
|
||||||
{
|
{
|
||||||
case ANM2_ATTRIBUTE_CREATED_BY:
|
case ANM2_ATTRIBUTE_CREATED_BY:
|
||||||
strncpy(self->createdBy, attribute->Value(), ANM2_STRING_MAX - 1);
|
strncpy(self->createdBy, xmlAttribute->Value(), ANM2_STRING_MAX - 1);
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_CREATED_ON:
|
case ANM2_ATTRIBUTE_CREATED_ON:
|
||||||
strncpy(self->createdOn, attribute->Value(), ANM2_STRING_MAX - 1);
|
strncpy(self->createdOn, xmlAttribute->Value(), ANM2_STRING_MAX - 1);
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_VERSION:
|
case ANM2_ATTRIBUTE_VERSION:
|
||||||
self->version = atoi(attribute->Value());
|
self->version = atoi(xmlAttribute->Value());
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_FPS:
|
case ANM2_ATTRIBUTE_FPS:
|
||||||
self->fps = atoi(attribute->Value());
|
self->fps = atoi(xmlAttribute->Value());
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_ID:
|
case ANM2_ATTRIBUTE_ID:
|
||||||
id = atoi(attribute->Value());
|
|
||||||
switch (anm2Element)
|
|
||||||
{
|
|
||||||
case ANM2_ELEMENT_SPRITESHEET:
|
|
||||||
self->spritesheets[id] = tempSpritesheet;
|
|
||||||
lastSpritesheet = &self->spritesheets[id];
|
|
||||||
break;
|
break;
|
||||||
case ANM2_ELEMENT_LAYER:
|
case ANM2_ATTRIBUTE_LAYER_ID:
|
||||||
self->layers[id] = tempLayer;
|
map_swap(animation->layerAnimations, id, atoi(xmlAttribute->Value()));
|
||||||
lastLayer = &self->layers[id];
|
|
||||||
break;
|
break;
|
||||||
case ANM2_ELEMENT_NULL:
|
case ANM2_ATTRIBUTE_NULL_ID:
|
||||||
self->nulls[id] = tempNull;
|
map_swap(animation->nullAnimations, id, atoi(xmlAttribute->Value()));
|
||||||
lastNull = &self->nulls[id];
|
|
||||||
break;
|
|
||||||
case ANM2_ELEMENT_EVENT:
|
|
||||||
self->events[id] = tempEvent;
|
|
||||||
lastEvent = &self->events[id];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_PATH:
|
case ANM2_ATTRIBUTE_PATH:
|
||||||
/* Make path lowercase */
|
strncpy(spritesheet->path, xmlAttribute->Value(), PATH_MAX - 1);
|
||||||
strncpy(lastSpritesheetPath, attribute->Value(), PATH_MAX - 1);
|
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_NAME:
|
case ANM2_ATTRIBUTE_NAME:
|
||||||
switch (anm2Element)
|
switch (anm2Element)
|
||||||
{
|
{
|
||||||
case ANM2_ELEMENT_LAYER:
|
case ANM2_ELEMENT_LAYER:
|
||||||
strncpy(lastLayer->name, attribute->Value(), ANM2_STRING_MAX - 1);
|
strncpy(layer->name, xmlAttribute->Value(), ANM2_STRING_MAX - 1);
|
||||||
break;
|
break;
|
||||||
case ANM2_ELEMENT_NULL:
|
case ANM2_ELEMENT_NULL:
|
||||||
strncpy(lastNull->name, attribute->Value(), ANM2_STRING_MAX - 1);
|
strncpy(null->name, xmlAttribute->Value(), ANM2_STRING_MAX - 1);
|
||||||
break;
|
break;
|
||||||
case ANM2_ELEMENT_ANIMATION:
|
case ANM2_ELEMENT_ANIMATION:
|
||||||
strncpy(lastAnimation->name, attribute->Value(), ANM2_STRING_MAX - 1);
|
strncpy(animation->name, xmlAttribute->Value(), ANM2_STRING_MAX - 1);
|
||||||
break;
|
break;
|
||||||
case ANM2_ELEMENT_EVENT:
|
case ANM2_ELEMENT_EVENT:
|
||||||
strncpy(lastEvent->name, attribute->Value(), ANM2_STRING_MAX - 1);
|
strncpy(event->name, xmlAttribute->Value(), ANM2_STRING_MAX - 1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_SPRITESHEET_ID:
|
case ANM2_ATTRIBUTE_SPRITESHEET_ID:
|
||||||
lastLayer->spritesheetID = atoi(attribute->Value());
|
layer->spritesheetID = atoi(xmlAttribute->Value());
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_SHOW_RECT:
|
case ANM2_ATTRIBUTE_SHOW_RECT:
|
||||||
switch (anm2Element)
|
null->isShowRect = string_to_bool(xmlAttribute->Value());
|
||||||
{
|
|
||||||
case ANM2_ELEMENT_NULL:
|
|
||||||
lastNull->isShowRect = string_to_bool(attribute->Value());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_DEFAULT_ANIMATION:
|
case ANM2_ATTRIBUTE_DEFAULT_ANIMATION:
|
||||||
strncpy(self->defaultAnimation, attribute->Value(), ANM2_STRING_MAX - 1);
|
strncpy(self->defaultAnimation, xmlAttribute->Value(), ANM2_STRING_MAX - 1);
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_FRAME_NUM:
|
case ANM2_ATTRIBUTE_FRAME_NUM:
|
||||||
lastAnimation->frameNum = atoi(attribute->Value());
|
animation->frameNum = atoi(xmlAttribute->Value());
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_LOOP:
|
case ANM2_ATTRIBUTE_LOOP:
|
||||||
lastAnimation->isLoop = string_to_bool(attribute->Value());
|
animation->isLoop = string_to_bool(xmlAttribute->Value());
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_X_POSITION:
|
case ANM2_ATTRIBUTE_X_POSITION:
|
||||||
lastFrame->position.x = atof(attribute->Value());
|
frame->position.x = atof(xmlAttribute->Value());
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_Y_POSITION:
|
case ANM2_ATTRIBUTE_Y_POSITION:
|
||||||
lastFrame->position.y = atof(attribute->Value());
|
frame->position.y = atof(xmlAttribute->Value());
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_X_PIVOT:
|
case ANM2_ATTRIBUTE_X_PIVOT:
|
||||||
lastFrame->pivot.x = atof(attribute->Value());
|
frame->pivot.x = atof(xmlAttribute->Value());
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_Y_PIVOT:
|
case ANM2_ATTRIBUTE_Y_PIVOT:
|
||||||
lastFrame->pivot.y = atof(attribute->Value());
|
frame->pivot.y = atof(xmlAttribute->Value());
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_X_CROP:
|
case ANM2_ATTRIBUTE_X_CROP:
|
||||||
lastFrame->crop.x = atof(attribute->Value());
|
frame->crop.x = atof(xmlAttribute->Value());
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_Y_CROP:
|
case ANM2_ATTRIBUTE_Y_CROP:
|
||||||
lastFrame->crop.y = atof(attribute->Value());
|
frame->crop.y = atof(xmlAttribute->Value());
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_WIDTH:
|
case ANM2_ATTRIBUTE_WIDTH:
|
||||||
lastFrame->size.x = atof(attribute->Value());
|
frame->size.x = atof(xmlAttribute->Value());
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_HEIGHT:
|
case ANM2_ATTRIBUTE_HEIGHT:
|
||||||
lastFrame->size.y = atof(attribute->Value());
|
frame->size.y = atof(xmlAttribute->Value());
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_X_SCALE:
|
case ANM2_ATTRIBUTE_X_SCALE:
|
||||||
lastFrame->scale.x = atof(attribute->Value());
|
frame->scale.x = atof(xmlAttribute->Value());
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_Y_SCALE:
|
case ANM2_ATTRIBUTE_Y_SCALE:
|
||||||
lastFrame->scale.y = atof(attribute->Value());
|
frame->scale.y = atof(xmlAttribute->Value());
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_DELAY:
|
case ANM2_ATTRIBUTE_DELAY:
|
||||||
lastFrame->delay = atoi(attribute->Value());
|
frame->delay = atoi(xmlAttribute->Value());
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_VISIBLE:
|
case ANM2_ATTRIBUTE_VISIBLE:
|
||||||
switch (anm2Element)
|
switch (anm2Element)
|
||||||
{
|
{
|
||||||
case ANM2_ELEMENT_FRAME:
|
case ANM2_ELEMENT_FRAME:
|
||||||
lastFrame->isVisible = string_to_bool(attribute->Value());
|
frame->isVisible = string_to_bool(xmlAttribute->Value());
|
||||||
break;
|
break;
|
||||||
case ANM2_LAYER_ANIMATION:
|
case ANM2_ELEMENT_ROOT_ANIMATION:
|
||||||
lastLayerAnimation->isVisible = string_to_bool(attribute->Value());
|
case ANM2_ELEMENT_LAYER_ANIMATION:
|
||||||
break;
|
case ANM2_ELEMENT_NULL_ANIMATION:
|
||||||
case ANM2_NULL_ANIMATION:
|
item->isVisible = string_to_bool(xmlAttribute->Value());
|
||||||
lastNullAnimation->isVisible = string_to_bool(attribute->Value());
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_RED_TINT:
|
case ANM2_ATTRIBUTE_RED_TINT:
|
||||||
lastFrame->tintRGBA.r = COLOR_INT_TO_FLOAT(atoi(attribute->Value()));
|
frame->tintRGBA.r = COLOR_INT_TO_FLOAT(atoi(xmlAttribute->Value()));
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_GREEN_TINT:
|
case ANM2_ATTRIBUTE_GREEN_TINT:
|
||||||
lastFrame->tintRGBA.g = COLOR_INT_TO_FLOAT(atoi(attribute->Value()));
|
frame->tintRGBA.g = COLOR_INT_TO_FLOAT(atoi(xmlAttribute->Value()));
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_BLUE_TINT:
|
case ANM2_ATTRIBUTE_BLUE_TINT:
|
||||||
lastFrame->tintRGBA.b = COLOR_INT_TO_FLOAT(atoi(attribute->Value()));
|
frame->tintRGBA.b = COLOR_INT_TO_FLOAT(atoi(xmlAttribute->Value()));
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_ALPHA_TINT:
|
case ANM2_ATTRIBUTE_ALPHA_TINT:
|
||||||
lastFrame->tintRGBA.a = COLOR_INT_TO_FLOAT(atoi(attribute->Value()));
|
frame->tintRGBA.a = COLOR_INT_TO_FLOAT(atoi(xmlAttribute->Value()));
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_RED_OFFSET:
|
case ANM2_ATTRIBUTE_RED_OFFSET:
|
||||||
lastFrame->offsetRGB.r = COLOR_INT_TO_FLOAT(atoi(attribute->Value()));
|
frame->offsetRGB.r = COLOR_INT_TO_FLOAT(atoi(xmlAttribute->Value()));
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_GREEN_OFFSET:
|
case ANM2_ATTRIBUTE_GREEN_OFFSET:
|
||||||
lastFrame->offsetRGB.g = COLOR_INT_TO_FLOAT(atoi(attribute->Value()));
|
frame->offsetRGB.g = COLOR_INT_TO_FLOAT(atoi(xmlAttribute->Value()));
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_BLUE_OFFSET:
|
case ANM2_ATTRIBUTE_BLUE_OFFSET:
|
||||||
lastFrame->offsetRGB.b = COLOR_INT_TO_FLOAT(atoi(attribute->Value()));
|
frame->offsetRGB.b = COLOR_INT_TO_FLOAT(atoi(xmlAttribute->Value()));
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_ROTATION:
|
case ANM2_ATTRIBUTE_ROTATION:
|
||||||
lastFrame->rotation = atof(attribute->Value());
|
frame->rotation = atof(xmlAttribute->Value());
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_INTERPOLATED:
|
case ANM2_ATTRIBUTE_INTERPOLATED:
|
||||||
lastFrame->isInterpolated = string_to_bool(attribute->Value());
|
frame->isInterpolated = string_to_bool(xmlAttribute->Value());
|
||||||
break;
|
|
||||||
case ANM2_ATTRIBUTE_LAYER_ID:
|
|
||||||
id = atoi(attribute->Value());
|
|
||||||
lastAnimation->layerAnimations[id] = Anm2LayerAnimation{};
|
|
||||||
lastLayerAnimation = &lastAnimation->layerAnimations[id];
|
|
||||||
break;
|
|
||||||
case ANM2_ATTRIBUTE_NULL_ID:
|
|
||||||
id = atoi(attribute->Value());
|
|
||||||
lastAnimation->nullAnimations[id] = Anm2NullAnimation{};
|
|
||||||
lastNullAnimation = &lastAnimation->nullAnimations[id];
|
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_EVENT_ID:
|
case ANM2_ATTRIBUTE_EVENT_ID:
|
||||||
lastTrigger->eventID = atoi(attribute->Value());
|
frame->eventID = atoi(xmlAttribute->Value());
|
||||||
break;
|
break;
|
||||||
case ANM2_ATTRIBUTE_AT_FRAME:
|
case ANM2_ATTRIBUTE_AT_FRAME:
|
||||||
lastTrigger->atFrame = atoi(attribute->Value());
|
frame->atFrame = atoi(xmlAttribute->Value());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
attribute = attribute->Next();
|
xmlAttribute = xmlAttribute->Next();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load spritesheet textures */
|
/* Load spritesheet textures */
|
||||||
if (anm2Element == ANM2_ELEMENT_SPRITESHEET)
|
if (anm2Element == ANM2_ELEMENT_SPRITESHEET)
|
||||||
{
|
anm2_spritesheet_texture_load(self, resources, spritesheet->path , id);
|
||||||
strncpy(lastSpritesheet->path, lastSpritesheetPath, PATH_MAX);
|
|
||||||
anm2_spritesheet_texture_load(self, resources, lastSpritesheetPath , id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Iterate through children */
|
/* Iterate through children */
|
||||||
child = element->FirstChildElement();
|
xmlChild = xmlElement->FirstChildElement();
|
||||||
|
|
||||||
if (child)
|
if (xmlChild)
|
||||||
{
|
{
|
||||||
element = child;
|
xmlElement = xmlChild;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Iterate through siblings */
|
/* Iterate through siblings */
|
||||||
while (element)
|
while (xmlElement)
|
||||||
{
|
{
|
||||||
const XMLElement* next;
|
const XMLElement* xmlNext;
|
||||||
|
|
||||||
next = element->NextSiblingElement();
|
xmlNext = xmlElement->NextSiblingElement();
|
||||||
|
|
||||||
if (next)
|
if (xmlNext)
|
||||||
{
|
{
|
||||||
element = next;
|
xmlElement = xmlNext;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If no siblings, return to parent. If no parent, end parsing */
|
/* If no siblings, return to parent. If no parent, end parsing */
|
||||||
element = element->Parent() ? element->Parent()->ToElement() : NULL;
|
xmlElement = xmlElement->Parent() ? xmlElement->Parent()->ToElement() : NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -665,7 +609,7 @@ anm2_layer_add(Anm2* self)
|
|||||||
self->layers[id] = Anm2Layer{};
|
self->layers[id] = Anm2Layer{};
|
||||||
|
|
||||||
for (auto & [animationID, animation] : self->animations)
|
for (auto & [animationID, animation] : self->animations)
|
||||||
animation.layerAnimations[id] = Anm2LayerAnimation{};
|
animation.layerAnimations[id] = Anm2Item{};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Removes a layer from the anm2 given the index/id */
|
/* Removes a layer from the anm2 given the index/id */
|
||||||
@@ -674,8 +618,8 @@ anm2_layer_remove(Anm2* self, s32 id)
|
|||||||
{
|
{
|
||||||
self->layers.erase(id);
|
self->layers.erase(id);
|
||||||
|
|
||||||
for (auto& animationPair : self->animations)
|
for (auto & [animationID, animation] : self->animations)
|
||||||
animationPair.second.layerAnimations.erase(id);
|
animation.layerAnimations.erase(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Adds a new null to the anm2 */
|
/* Adds a new null to the anm2 */
|
||||||
@@ -687,7 +631,7 @@ anm2_null_add(Anm2* self)
|
|||||||
self->nulls[id] = Anm2Null{};
|
self->nulls[id] = Anm2Null{};
|
||||||
|
|
||||||
for (auto & [animationID, animation] : self->animations)
|
for (auto & [animationID, animation] : self->animations)
|
||||||
animation.nullAnimations[id] = Anm2NullAnimation{};
|
animation.nullAnimations[id] = Anm2Item{};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Removes a null from the anm2 given the index/id */
|
/* Removes a null from the anm2 given the index/id */
|
||||||
@@ -696,8 +640,8 @@ anm2_null_remove(Anm2* self, s32 id)
|
|||||||
{
|
{
|
||||||
self->nulls.erase(id);
|
self->nulls.erase(id);
|
||||||
|
|
||||||
for (auto& animationPair : self->animations)
|
for (auto & [animationID, animation] : self->animations)
|
||||||
animationPair.second.nullAnimations.erase(id);
|
animation.nullAnimations.erase(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Adds a new animation to the anm2, makes sure to keep the layeranimations/nullsanimation check */
|
/* Adds a new animation to the anm2, makes sure to keep the layeranimations/nullsanimation check */
|
||||||
@@ -710,13 +654,13 @@ anm2_animation_add(Anm2* self)
|
|||||||
/* match layers */
|
/* match layers */
|
||||||
for (auto & [layerID, layer] : self->layers)
|
for (auto & [layerID, layer] : self->layers)
|
||||||
{
|
{
|
||||||
animation.layerAnimations[layerID] = Anm2LayerAnimation{};
|
animation.layerAnimations[layerID] = Anm2Item{};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* match nulls */
|
/* match nulls */
|
||||||
for (auto & [nullID, null] : self->nulls)
|
for (auto & [nullID, null] : self->nulls)
|
||||||
{
|
{
|
||||||
animation.nullAnimations[nullID] = Anm2NullAnimation{};
|
animation.nullAnimations[nullID] = Anm2Item{};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add a root frame */
|
/* add a root frame */
|
||||||
@@ -757,69 +701,104 @@ anm2_spritesheet_texture_load(Anm2* self, Resources* resources, const char* path
|
|||||||
resources->textures[id] = texture;
|
resources->textures[id] = texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Creates/fetches a frame from a given time. */
|
Anm2Animation*
|
||||||
/* Returns true/false if frame will be valid or not. */
|
anm2_animation_from_id(Anm2* self, s32 animationID)
|
||||||
bool
|
|
||||||
anm2_frame_from_time(Anm2* self, Anm2Animation* animation, Anm2Frame* frame, Anm2AnimationType type, s32 id, f32 time)
|
|
||||||
{
|
{
|
||||||
/* Out of range */
|
auto it = self->animations.find(animationID);
|
||||||
if (time < 0 || time > animation->frameNum)
|
if (it == self->animations.end())
|
||||||
return false;
|
return NULL;
|
||||||
|
return &it->second;
|
||||||
Anm2RootAnimation* rootAnimation;
|
|
||||||
Anm2LayerAnimation* layerAnimation;
|
|
||||||
Anm2NullAnimation* nullAnimation;
|
|
||||||
Anm2Frame* nextFrame = NULL;
|
|
||||||
std::vector<Anm2Frame>* frames = NULL;
|
|
||||||
f32 delayCurrent = 0;
|
|
||||||
f32 delayNext = 0;
|
|
||||||
bool isTimeMatchedFrame = false;
|
|
||||||
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case ANM2_ROOT_ANIMATION:
|
|
||||||
frames = &animation->rootAnimation.frames;
|
|
||||||
break;
|
|
||||||
case ANM2_LAYER_ANIMATION:
|
|
||||||
if (id < 0 || id >= (s32)animation->layerAnimations.size())
|
|
||||||
return false;
|
|
||||||
frames = &animation->layerAnimations[id].frames;
|
|
||||||
break;
|
|
||||||
case ANM2_NULL_ANIMATION:
|
|
||||||
if (id < 0 || id >= (s32)animation->nullAnimations.size())
|
|
||||||
return false;
|
|
||||||
frames = &animation->nullAnimations[id].frames;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (s32 i = 0; i < (s32)frames->size(); i++)
|
/* Returns the item from a anm2 reference. */
|
||||||
|
Anm2Item*
|
||||||
|
anm2_item_from_reference(Anm2* self, Anm2Reference* reference, s32 animationID)
|
||||||
{
|
{
|
||||||
*frame = (*frames)[i];
|
Anm2Animation* animation = anm2_animation_from_id(self, animationID);
|
||||||
|
|
||||||
|
if (!animation)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
switch (reference->type)
|
||||||
|
{
|
||||||
|
case ANM2_ROOT:
|
||||||
|
return &animation->rootAnimation;
|
||||||
|
case ANM2_LAYER:
|
||||||
|
{
|
||||||
|
auto it = animation->layerAnimations.find(reference->id);
|
||||||
|
if (it == animation->layerAnimations.end())
|
||||||
|
return NULL;
|
||||||
|
return &it->second;
|
||||||
|
}
|
||||||
|
case ANM2_NULL:
|
||||||
|
{
|
||||||
|
auto it = animation->nullAnimations.find(reference->id);
|
||||||
|
if (it == animation->nullAnimations.end())
|
||||||
|
return NULL;
|
||||||
|
return &it->second;
|
||||||
|
}
|
||||||
|
case ANM2_TRIGGERS:
|
||||||
|
return &animation->triggers;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Gets the frame from the reference's properties */
|
||||||
|
Anm2Frame*
|
||||||
|
anm2_frame_from_reference(Anm2* self, Anm2Reference* reference, s32 animationID)
|
||||||
|
{
|
||||||
|
Anm2Item* item = anm2_item_from_reference(self, reference, animationID);
|
||||||
|
|
||||||
|
if (!item)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (reference->index < 0 || reference->index >= (s32)item->frames.size())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return &item->frames[reference->index];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Creates/fetches a frame from a given time. */
|
||||||
|
/* Returns true/false if frame will be valid or not. */
|
||||||
|
void
|
||||||
|
anm2_frame_from_time(Anm2* self, Anm2Frame* frame, Anm2Reference reference, s32 animationID, f32 time)
|
||||||
|
{
|
||||||
|
Anm2Animation* animation = anm2_animation_from_id(self, animationID);
|
||||||
|
|
||||||
|
/* Out of range */
|
||||||
|
if (time < 0 || time > animation->frameNum)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Anm2Item* item = anm2_item_from_reference(self, &reference, animationID);
|
||||||
|
|
||||||
|
if (!item)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Anm2Frame* nextFrame = NULL;
|
||||||
|
s32 delayCurrent = 0;
|
||||||
|
s32 delayNext = 0;
|
||||||
|
|
||||||
|
for (s32 i = 0; i < (s32)item->frames.size(); i++)
|
||||||
|
{
|
||||||
|
*frame = item->frames[i];
|
||||||
delayNext += frame->delay;
|
delayNext += frame->delay;
|
||||||
|
|
||||||
/* If a frame is within the time constraints, it's a time matched frame, break */
|
/* If a frame is within the time constraints, it's a time matched frame, break */
|
||||||
/* Otherwise, the last found frame parsed will be used. */
|
/* Otherwise, the last found frame parsed will be used. */
|
||||||
if (time >= delayCurrent && time < delayNext)
|
if (time >= delayCurrent && time < delayNext)
|
||||||
{
|
{
|
||||||
if (i + 1 < (s32)frames->size())
|
if (i + 1 < (s32)item->frames.size())
|
||||||
nextFrame = &(*frames)[i + 1];
|
nextFrame = &item->frames[i + 1];
|
||||||
else
|
else
|
||||||
nextFrame = NULL;
|
nextFrame = NULL;
|
||||||
|
|
||||||
isTimeMatchedFrame = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
delayCurrent += frame->delay;
|
delayCurrent += frame->delay;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No valid frame found */
|
/* Interpolate only if there's a frame following */
|
||||||
if (!isTimeMatchedFrame)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
/* interpolate only if there's a frame following */
|
|
||||||
if (frame->isInterpolated && nextFrame)
|
if (frame->isInterpolated && nextFrame)
|
||||||
{
|
{
|
||||||
f32 interpolationTime = (time - delayCurrent) / (delayNext - delayCurrent);
|
f32 interpolationTime = (time - delayCurrent) / (delayNext - delayCurrent);
|
||||||
@@ -830,6 +809,67 @@ anm2_frame_from_time(Anm2* self, Anm2Animation* animation, Anm2Frame* frame, Anm
|
|||||||
frame->offsetRGB = glm::mix(frame->offsetRGB, nextFrame->offsetRGB, interpolationTime);;
|
frame->offsetRGB = glm::mix(frame->offsetRGB, nextFrame->offsetRGB, interpolationTime);;
|
||||||
frame->tintRGBA = glm::mix(frame->tintRGBA, nextFrame->tintRGBA, interpolationTime);;
|
frame->tintRGBA = glm::mix(frame->tintRGBA, nextFrame->tintRGBA, interpolationTime);;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return true;
|
|
||||||
|
/* Will try adding a frame to the anm2 given the specified reference */
|
||||||
|
Anm2Frame*
|
||||||
|
anm2_frame_add(Anm2* self, Anm2Reference* reference, s32 animationID, s32 time)
|
||||||
|
{
|
||||||
|
Anm2Animation* animation = anm2_animation_from_id(self, animationID);
|
||||||
|
Anm2Item* item = anm2_item_from_reference(self, reference, animationID);
|
||||||
|
|
||||||
|
if (!animation || !item)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (item)
|
||||||
|
{
|
||||||
|
Anm2Frame frame = Anm2Frame{};
|
||||||
|
s32 index = -1;
|
||||||
|
|
||||||
|
if (reference->type == ANM2_TRIGGERS)
|
||||||
|
{
|
||||||
|
/* don't add redudant triggers (i.e. at same time) */
|
||||||
|
for (auto & frameCheck : item->frames)
|
||||||
|
{
|
||||||
|
if (frameCheck.atFrame == time)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
frame.atFrame = time;
|
||||||
|
index = item->frames.size();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s32 delay = 0;
|
||||||
|
s32 frameDelayCount = 0;
|
||||||
|
|
||||||
|
/* Add up all delay to see where this new frame might lie */
|
||||||
|
for (auto & frameCheck : item->frames)
|
||||||
|
frameDelayCount += frameCheck.delay;
|
||||||
|
|
||||||
|
/* If adding the smallest frame would be over the length, don't bother */
|
||||||
|
if (frameDelayCount + ANM2_FRAME_DELAY_MIN > animation->frameNum)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Will insert next to frame if frame exists */
|
||||||
|
Anm2Frame* checkFrame = anm2_frame_from_reference(self, reference, animationID);
|
||||||
|
|
||||||
|
if (checkFrame)
|
||||||
|
{
|
||||||
|
/* Will shrink frame delay to fit */
|
||||||
|
if (frameDelayCount + checkFrame->delay > animation->frameNum)
|
||||||
|
frame.delay = animation->frameNum - frameDelayCount;
|
||||||
|
|
||||||
|
index = reference->index + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
index = (s32)item->frames.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
item->frames.insert(item->frames.begin() + index, frame);
|
||||||
|
|
||||||
|
return &item->frames[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
66
src/anm2.h
66
src/anm2.h
@@ -14,6 +14,7 @@
|
|||||||
#define ANM2_FPS_MAX 120
|
#define ANM2_FPS_MAX 120
|
||||||
#define ANM2_FRAME_NUM_MIN 1
|
#define ANM2_FRAME_NUM_MIN 1
|
||||||
#define ANM2_FRAME_NUM_MAX 1000000
|
#define ANM2_FRAME_NUM_MAX 1000000
|
||||||
|
#define ANM2_FRAME_DELAY_MIN 1
|
||||||
|
|
||||||
/* Elements */
|
/* Elements */
|
||||||
#define ANM2_ELEMENT_LIST \
|
#define ANM2_ELEMENT_LIST \
|
||||||
@@ -108,14 +109,14 @@ static const char* ANM2_ATTRIBUTE_STRINGS[] = {
|
|||||||
|
|
||||||
DEFINE_STRING_TO_ENUM_FN(anm2_attribute_from_string, Anm2Attribute, ANM2_ATTRIBUTE_STRINGS, ANM2_ATTRIBUTE_COUNT)
|
DEFINE_STRING_TO_ENUM_FN(anm2_attribute_from_string, Anm2Attribute, ANM2_ATTRIBUTE_STRINGS, ANM2_ATTRIBUTE_COUNT)
|
||||||
|
|
||||||
#define ANM2_ANIMATION_TYPE_COUNT (ANM2_ANIMATION_TRIGGERS + 1)
|
#define ANM2_COUNT (ANM2_TRIGGER + 1)
|
||||||
enum Anm2AnimationType
|
enum Anm2Type
|
||||||
{
|
{
|
||||||
ANM2_NONE,
|
ANM2_NONE,
|
||||||
ANM2_ROOT_ANIMATION,
|
ANM2_ROOT,
|
||||||
ANM2_LAYER_ANIMATION,
|
ANM2_LAYER,
|
||||||
ANM2_NULL_ANIMATION,
|
ANM2_NULL,
|
||||||
ANM2_TRIGGER
|
ANM2_TRIGGERS
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Anm2Spritesheet
|
struct Anm2Spritesheet
|
||||||
@@ -140,18 +141,14 @@ struct Anm2Event
|
|||||||
char name[ANM2_STRING_MAX] = STRING_ANM2_NEW_EVENT;
|
char name[ANM2_STRING_MAX] = STRING_ANM2_NEW_EVENT;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Anm2Trigger
|
|
||||||
{
|
|
||||||
s32 eventID = -1;
|
|
||||||
s32 atFrame = -1;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Anm2Frame
|
struct Anm2Frame
|
||||||
{
|
{
|
||||||
bool isInterpolated = false;
|
bool isInterpolated = false;
|
||||||
bool isVisible = true;
|
bool isVisible = true;
|
||||||
f32 rotation = 1.0f;
|
f32 rotation = 1.0f;
|
||||||
s32 delay = 1;
|
s32 delay = ANM2_FRAME_DELAY_MIN;
|
||||||
|
s32 atFrame = -1;
|
||||||
|
s32 eventID = -1;
|
||||||
vec2 crop = {0.0f, 0.0f};
|
vec2 crop = {0.0f, 0.0f};
|
||||||
vec2 pivot = {0.0f, 0.0f};
|
vec2 pivot = {0.0f, 0.0f};
|
||||||
vec2 position = {0.0f, 0.0f};
|
vec2 position = {0.0f, 0.0f};
|
||||||
@@ -161,39 +158,21 @@ struct Anm2Frame
|
|||||||
vec4 tintRGBA = {1.0f, 1.0f, 1.0f, 1.0f};
|
vec4 tintRGBA = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Anm2LayerAnimation
|
struct Anm2Item
|
||||||
{
|
{
|
||||||
bool isVisible = true;
|
bool isVisible = true;
|
||||||
std::vector<Anm2Frame> frames;
|
std::vector<Anm2Frame> frames;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Anm2NullAnimation
|
|
||||||
{
|
|
||||||
bool isVisible = true;
|
|
||||||
std::vector<Anm2Frame> frames;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Anm2RootAnimation
|
|
||||||
{
|
|
||||||
bool isVisible = true;
|
|
||||||
std::vector<Anm2Frame> frames;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Anm2Triggers
|
|
||||||
{
|
|
||||||
bool isVisible = true;
|
|
||||||
std::vector<Anm2Trigger> items;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Anm2Animation
|
struct Anm2Animation
|
||||||
{
|
{
|
||||||
s32 frameNum = ANM2_FRAME_NUM_MIN;
|
s32 frameNum = ANM2_FRAME_NUM_MIN;
|
||||||
char name[ANM2_STRING_MAX] = STRING_ANM2_NEW_ANIMATION;
|
char name[ANM2_STRING_MAX] = STRING_ANM2_NEW_ANIMATION;
|
||||||
bool isLoop = true;
|
bool isLoop = true;
|
||||||
Anm2RootAnimation rootAnimation;
|
Anm2Item rootAnimation;
|
||||||
std::map<s32, Anm2LayerAnimation> layerAnimations;
|
std::map<s32, Anm2Item> layerAnimations;
|
||||||
std::map<s32, Anm2NullAnimation> nullAnimations;
|
std::map<s32, Anm2Item> nullAnimations;
|
||||||
Anm2Triggers triggers;
|
Anm2Item triggers;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Anm2
|
struct Anm2
|
||||||
@@ -211,6 +190,15 @@ struct Anm2
|
|||||||
std::map<s32, Anm2Animation> animations;
|
std::map<s32, Anm2Animation> animations;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Anm2Reference
|
||||||
|
{
|
||||||
|
Anm2Type type = ANM2_NONE;
|
||||||
|
s32 id = -1;
|
||||||
|
s32 index = -1;
|
||||||
|
|
||||||
|
auto operator<=>(const Anm2Reference&) const = default;
|
||||||
|
};
|
||||||
|
|
||||||
void anm2_layer_add(Anm2* self);
|
void anm2_layer_add(Anm2* self);
|
||||||
void anm2_layer_remove(Anm2* self, s32 id);
|
void anm2_layer_remove(Anm2* self, s32 id);
|
||||||
void anm2_null_add(Anm2* self);
|
void anm2_null_add(Anm2* self);
|
||||||
@@ -222,4 +210,8 @@ void anm2_created_on_set(Anm2* self);
|
|||||||
s32 anm2_animation_add(Anm2* self);
|
s32 anm2_animation_add(Anm2* self);
|
||||||
void anm2_animation_remove(Anm2* self, s32 id);
|
void anm2_animation_remove(Anm2* self, s32 id);
|
||||||
void anm2_spritesheet_texture_load(Anm2* self, Resources* resources, const char* path, s32 id);
|
void anm2_spritesheet_texture_load(Anm2* self, Resources* resources, const char* path, s32 id);
|
||||||
bool anm2_frame_from_time(Anm2* self, Anm2Animation* animation, Anm2Frame* frame, Anm2AnimationType type, s32 id, f32 time);
|
Anm2Animation* anm2_animation_from_id(Anm2* self, s32 animationID);
|
||||||
|
Anm2Item* anm2_item_from_reference(Anm2* self, Anm2Reference* reference, s32 animationID);
|
||||||
|
Anm2Frame* anm2_frame_from_reference(Anm2* self, Anm2Reference* reference, s32 animationID);
|
||||||
|
Anm2Frame* anm2_frame_add(Anm2* self, Anm2Reference* reference, s32 animationID, s32 time);
|
||||||
|
void anm2_frame_from_time(Anm2* self, Anm2Frame* frame, Anm2Reference reference, s32 animationID, f32 time);
|
@@ -19,9 +19,10 @@ _dialog_callback(void* userdata, const char* const* filelist, s32 filter)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
dialog_init(Dialog* self, Anm2* anm2, Resources* resources, SDL_Window* window)
|
dialog_init(Dialog* self, Anm2* anm2, Anm2Reference* reference, Resources* resources, SDL_Window* window)
|
||||||
{
|
{
|
||||||
self->anm2 = anm2;
|
self->anm2 = anm2;
|
||||||
|
self->reference = reference;
|
||||||
self->resources = resources;
|
self->resources = resources;
|
||||||
self->window = window;
|
self->window = window;
|
||||||
}
|
}
|
||||||
@@ -76,6 +77,7 @@ dialog_tick(Dialog* self)
|
|||||||
switch (self->type)
|
switch (self->type)
|
||||||
{
|
{
|
||||||
case DIALOG_ANM2_OPEN:
|
case DIALOG_ANM2_OPEN:
|
||||||
|
*self->reference = Anm2Reference{};
|
||||||
resources_textures_free(self->resources);
|
resources_textures_free(self->resources);
|
||||||
anm2_deserialize(self->anm2, self->resources, self->path);
|
anm2_deserialize(self->anm2, self->resources, self->path);
|
||||||
window_title_from_anm2_set(self->window, self->anm2);
|
window_title_from_anm2_set(self->window, self->anm2);
|
||||||
|
@@ -26,6 +26,7 @@ enum DialogType
|
|||||||
struct Dialog
|
struct Dialog
|
||||||
{
|
{
|
||||||
Anm2* anm2 = NULL;
|
Anm2* anm2 = NULL;
|
||||||
|
Anm2Reference* reference = NULL;
|
||||||
Resources* resources = NULL;
|
Resources* resources = NULL;
|
||||||
SDL_Window* window = NULL;
|
SDL_Window* window = NULL;
|
||||||
s32 replaceID = -1;
|
s32 replaceID = -1;
|
||||||
@@ -34,7 +35,7 @@ struct Dialog
|
|||||||
bool isSelected = false;
|
bool isSelected = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
void dialog_init(Dialog* self, Anm2* anm2, Resources* resources, SDL_Window* window);
|
void dialog_init(Dialog* self, Anm2* anm2, Anm2Reference* reference, Resources* resources, SDL_Window* window);
|
||||||
void dialog_anm2_open(Dialog* self);
|
void dialog_anm2_open(Dialog* self);
|
||||||
void dialog_png_open(Dialog* self);
|
void dialog_png_open(Dialog* self);
|
||||||
void dialog_png_replace(Dialog* self);
|
void dialog_png_replace(Dialog* self);
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
#include "editor.h"
|
#include "editor.h"
|
||||||
|
|
||||||
static void _editor_grid_set(Editor* self);
|
static s32 _editor_grid_set(Editor* self);
|
||||||
|
|
||||||
static void
|
static s32
|
||||||
_editor_grid_set(Editor* self)
|
_editor_grid_set(Editor* self)
|
||||||
{
|
{
|
||||||
std::vector<f32> vertices;
|
std::vector<f32> vertices;
|
||||||
@@ -34,19 +34,32 @@ _editor_grid_set(Editor* self)
|
|||||||
vertices.push_back(normY);
|
vertices.push_back(normY);
|
||||||
}
|
}
|
||||||
|
|
||||||
self->gridVertexCount = (s32)vertices.size();
|
|
||||||
|
|
||||||
glBindVertexArray(self->gridVAO);
|
glBindVertexArray(self->gridVAO);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, self->gridVBO);
|
glBindBuffer(GL_ARRAY_BUFFER, self->gridVBO);
|
||||||
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(f32), vertices.data(), GL_DYNAMIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(f32), vertices.data(), GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(f32), (void*)0);
|
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(f32), (void*)0);
|
||||||
|
|
||||||
|
return (s32)vertices.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
editor_init(Editor* self, Resources* resources, Settings* settings)
|
editor_init
|
||||||
|
(
|
||||||
|
Editor* self,
|
||||||
|
Anm2* anm2,
|
||||||
|
Anm2Reference* reference,
|
||||||
|
s32* animationID,
|
||||||
|
s32* spritesheetID,
|
||||||
|
Resources* resources,
|
||||||
|
Settings* settings
|
||||||
|
)
|
||||||
{
|
{
|
||||||
|
self->anm2 = anm2;
|
||||||
|
self->reference = reference;
|
||||||
|
self->animationID = animationID;
|
||||||
|
self->spritesheetID = spritesheetID;
|
||||||
self->resources = resources;
|
self->resources = resources;
|
||||||
self->settings = settings;
|
self->settings = settings;
|
||||||
|
|
||||||
@@ -140,9 +153,9 @@ editor_draw(Editor* self)
|
|||||||
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
if (self->spritesheetID > -1)
|
if (*self->spritesheetID > -1)
|
||||||
{
|
{
|
||||||
Texture* texture = &self->resources->textures[self->spritesheetID];
|
Texture* texture = &self->resources->textures[*self->spritesheetID];
|
||||||
|
|
||||||
glm::mat4 spritesheetTransform = editorTransform;
|
glm::mat4 spritesheetTransform = editorTransform;
|
||||||
glm::vec2 ndcScale = glm::vec2(texture->size.x, texture->size.y) / (EDITOR_SIZE * 0.5f);
|
glm::vec2 ndcScale = glm::vec2(texture->size.x, texture->size.y) / (EDITOR_SIZE * 0.5f);
|
||||||
@@ -186,12 +199,16 @@ editor_draw(Editor* self)
|
|||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->isFrame)
|
Anm2Frame* frame = (Anm2Frame*)anm2_frame_from_reference(self->anm2, self->reference, *self->animationID);
|
||||||
|
|
||||||
|
/* Draw the layer frame's crop and pivot */
|
||||||
|
if (frame && self->reference->type == ANM2_LAYER)
|
||||||
{
|
{
|
||||||
|
/* Rect */
|
||||||
glm::mat4 rectTransform = editorTransform;
|
glm::mat4 rectTransform = editorTransform;
|
||||||
|
|
||||||
glm::vec2 rectNDCPos = self->frame.crop / (EDITOR_SIZE / 2.0f);
|
glm::vec2 rectNDCPos = frame->crop / (EDITOR_SIZE / 2.0f);
|
||||||
glm::vec2 rectNDCScale = self->frame.size / (EDITOR_SIZE * 0.5f);
|
glm::vec2 rectNDCScale = frame->size / (EDITOR_SIZE / 2.0f);
|
||||||
|
|
||||||
rectTransform = glm::translate(rectTransform, glm::vec3(rectNDCPos, 0.0f));
|
rectTransform = glm::translate(rectTransform, glm::vec3(rectNDCPos, 0.0f));
|
||||||
rectTransform = glm::scale(rectTransform, glm::vec3(rectNDCScale, 1.0f));
|
rectTransform = glm::scale(rectTransform, glm::vec3(rectNDCScale, 1.0f));
|
||||||
@@ -208,9 +225,10 @@ editor_draw(Editor* self)
|
|||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
|
|
||||||
|
/* Pivot */
|
||||||
glm::mat4 pivotTransform = editorTransform;
|
glm::mat4 pivotTransform = editorTransform;
|
||||||
glm::vec2 pivotNDCPos = self->frame.pivot / (EDITOR_SIZE / 2.0f);
|
glm::vec2 pivotNDCPos = ((frame->crop + frame->pivot) - (EDITOR_PIVOT_SIZE / 2.0f)) / (EDITOR_SIZE / 2.0f);
|
||||||
glm::vec2 pivotNDCScale = ATLAS_SIZES[TEXTURE_PIVOT] / (EDITOR_SIZE * 0.5f);
|
glm::vec2 pivotNDCScale = EDITOR_PIVOT_SIZE / (EDITOR_SIZE / 2.0f);
|
||||||
|
|
||||||
pivotTransform = glm::translate(pivotTransform, glm::vec3(pivotNDCPos, 0.0f));
|
pivotTransform = glm::translate(pivotTransform, glm::vec3(pivotNDCPos, 0.0f));
|
||||||
pivotTransform = glm::scale(pivotTransform, glm::vec3(pivotNDCScale, 1.0f));
|
pivotTransform = glm::scale(pivotTransform, glm::vec3(pivotNDCScale, 1.0f));
|
||||||
@@ -244,16 +262,21 @@ editor_draw(Editor* self)
|
|||||||
|
|
||||||
if (self->settings->editorIsGrid)
|
if (self->settings->editorIsGrid)
|
||||||
{
|
{
|
||||||
if
|
static ivec2 previousGridSize = {-1, -1};
|
||||||
(
|
static ivec2 previousGridOffset = {-1, -1};
|
||||||
(ivec2(self->settings->editorGridSizeX, self->settings->editorGridSizeY) != self->oldGridSize) ||
|
static s32 gridVertexCount = -1;
|
||||||
(ivec2(self->settings->editorGridOffsetX, self->settings->editorGridOffsetY) != self->oldGridOffset)
|
ivec2 gridSize = ivec2(self->settings->editorGridSizeX, self->settings->editorGridSizeY);
|
||||||
)
|
ivec2 gridOffset = ivec2(self->settings->editorGridOffsetX, self->settings->editorGridOffsetY);
|
||||||
_editor_grid_set(self);
|
|
||||||
|
if (previousGridSize != gridSize || previousGridOffset != gridOffset)
|
||||||
|
{
|
||||||
|
gridVertexCount = _editor_grid_set(self);
|
||||||
|
previousGridSize = gridSize;
|
||||||
|
previousGridOffset = gridOffset;
|
||||||
|
}
|
||||||
|
|
||||||
glUseProgram(shaderLine);
|
glUseProgram(shaderLine);
|
||||||
glBindVertexArray(self->gridVAO);
|
glBindVertexArray(self->gridVAO);
|
||||||
|
|
||||||
glUniformMatrix4fv(glGetUniformLocation(shaderLine, SHADER_UNIFORM_TRANSFORM), 1, GL_FALSE, (f32*)value_ptr(editorTransform));
|
glUniformMatrix4fv(glGetUniformLocation(shaderLine, SHADER_UNIFORM_TRANSFORM), 1, GL_FALSE, (f32*)value_ptr(editorTransform));
|
||||||
|
|
||||||
glUniform4f
|
glUniform4f
|
||||||
@@ -262,7 +285,7 @@ editor_draw(Editor* self)
|
|||||||
self->settings->editorGridColorR, self->settings->editorGridColorG, self->settings->editorGridColorB, self->settings->editorGridColorA
|
self->settings->editorGridColorR, self->settings->editorGridColorG, self->settings->editorGridColorB, self->settings->editorGridColorA
|
||||||
);
|
);
|
||||||
|
|
||||||
glDrawArrays(GL_LINES, 0, self->gridVertexCount);
|
glDrawArrays(GL_LINES, 0, gridVertexCount);
|
||||||
|
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
@@ -275,8 +298,6 @@ void
|
|||||||
editor_tick(Editor* self)
|
editor_tick(Editor* self)
|
||||||
{
|
{
|
||||||
self->settings->editorZoom = CLAMP(self->settings->editorZoom, EDITOR_ZOOM_MIN, EDITOR_ZOOM_MAX);
|
self->settings->editorZoom = CLAMP(self->settings->editorZoom, EDITOR_ZOOM_MIN, EDITOR_ZOOM_MAX);
|
||||||
self->oldGridSize = glm::vec2(self->settings->editorGridSizeX, self->settings->editorGridSizeY);
|
|
||||||
self->oldGridOffset = glm::vec2(self->settings->editorGridOffsetX, self->settings->editorGridOffsetY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
24
src/editor.h
24
src/editor.h
@@ -13,12 +13,17 @@
|
|||||||
#define EDITOR_GRID_OFFSET_MAX 100
|
#define EDITOR_GRID_OFFSET_MAX 100
|
||||||
|
|
||||||
static const vec2 EDITOR_SIZE = {5000, 5000};
|
static const vec2 EDITOR_SIZE = {5000, 5000};
|
||||||
|
static const vec2 EDITOR_PIVOT_SIZE = {4, 4};
|
||||||
static const vec4 EDITOR_TEXTURE_TINT = COLOR_OPAQUE;
|
static const vec4 EDITOR_TEXTURE_TINT = COLOR_OPAQUE;
|
||||||
static const vec4 EDITOR_BORDER_TINT = COLOR_OPAQUE;
|
static const vec4 EDITOR_BORDER_TINT = COLOR_OPAQUE;
|
||||||
static const vec4 EDITOR_FRAME_TINT = COLOR_RED;
|
static const vec4 EDITOR_FRAME_TINT = COLOR_RED;
|
||||||
|
|
||||||
struct Editor
|
struct Editor
|
||||||
{
|
{
|
||||||
|
Anm2* anm2 = NULL;
|
||||||
|
Anm2Reference* reference = NULL;
|
||||||
|
s32* animationID = NULL;
|
||||||
|
s32* spritesheetID = NULL;
|
||||||
Resources* resources = NULL;
|
Resources* resources = NULL;
|
||||||
Settings* settings = NULL;
|
Settings* settings = NULL;
|
||||||
GLuint fbo;
|
GLuint fbo;
|
||||||
@@ -31,16 +36,19 @@ struct Editor
|
|||||||
GLuint textureVBO;
|
GLuint textureVBO;
|
||||||
GLuint borderVAO;
|
GLuint borderVAO;
|
||||||
GLuint borderVBO;
|
GLuint borderVBO;
|
||||||
s32 gridVertexCount = -1;
|
|
||||||
s32 spritesheetID = -1;
|
|
||||||
s32 oldSpritesheetID = -1;
|
|
||||||
ivec2 oldGridSize = {-1, -1};
|
|
||||||
ivec2 oldGridOffset = {-1, -1};
|
|
||||||
Anm2Frame frame;
|
|
||||||
bool isFrame = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void editor_init(Editor* self, Resources* resources, Settings* settings);
|
void editor_init
|
||||||
|
(
|
||||||
|
Editor* self,
|
||||||
|
Anm2* anm2,
|
||||||
|
Anm2Reference* reference,
|
||||||
|
s32* animationID,
|
||||||
|
s32* spritesheetID,
|
||||||
|
Resources* resources,
|
||||||
|
Settings* settings
|
||||||
|
);
|
||||||
|
|
||||||
void editor_draw(Editor* self);
|
void editor_draw(Editor* self);
|
||||||
void editor_tick(Editor* self);
|
void editor_tick(Editor* self);
|
||||||
void editor_free(Editor* self);
|
void editor_free(Editor* self);
|
1181
src/imgui.cpp
1181
src/imgui.cpp
File diff suppressed because it is too large
Load Diff
50
src/imgui.h
50
src/imgui.h
@@ -7,6 +7,7 @@
|
|||||||
#include "window.h"
|
#include "window.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
#include "tool.h"
|
||||||
|
|
||||||
#define IMGUI_IMPL_OPENGL_LOADER_CUSTOM
|
#define IMGUI_IMPL_OPENGL_LOADER_CUSTOM
|
||||||
#define IMGUI_ENABLE_DOCKING
|
#define IMGUI_ENABLE_DOCKING
|
||||||
@@ -15,8 +16,6 @@
|
|||||||
#include <imgui/backends/imgui_impl_sdl3.h>
|
#include <imgui/backends/imgui_impl_sdl3.h>
|
||||||
#include <imgui/backends/imgui_impl_opengl3.h>
|
#include <imgui/backends/imgui_impl_opengl3.h>
|
||||||
|
|
||||||
|
|
||||||
#define IMGUI_TIMELINE_ELEMENT_WIDTH 300
|
|
||||||
#define IMGUI_TIMELINE_ELEMENT_WIDTH 300
|
#define IMGUI_TIMELINE_ELEMENT_WIDTH 300
|
||||||
|
|
||||||
#define IMGUI_DRAG_SPEED 1.0
|
#define IMGUI_DRAG_SPEED 1.0
|
||||||
@@ -32,15 +31,15 @@
|
|||||||
#define IMGUI_PICKER_LINE_COLOR IM_COL32(255, 255, 255, 255)
|
#define IMGUI_PICKER_LINE_COLOR IM_COL32(255, 255, 255, 255)
|
||||||
#define IMGUI_TOOLS_WIDTH_INCREMENT -2
|
#define IMGUI_TOOLS_WIDTH_INCREMENT -2
|
||||||
|
|
||||||
|
#define IMGUI_POSITION_STRING_MAX 0xFF
|
||||||
|
|
||||||
static const vec2 IMGUI_TASKBAR_MARGINS = {8, 4};
|
static const vec2 IMGUI_TASKBAR_MARGINS = {8, 4};
|
||||||
|
static const vec2 IMGUI_SPRITESHEET_EDITOR_CROP_FORGIVENESS = {1, 1};
|
||||||
|
|
||||||
static const ImVec2 IMGUI_ANIMATION_PREVIEW_SETTINGS_SIZE = {1280, 105};
|
static const ImVec2 IMGUI_ANIMATION_PREVIEW_SETTINGS_SIZE = {1280, 105};
|
||||||
static const ImVec2 IMGUI_ANIMATION_PREVIEW_SETTINGS_CHILD_SIZE = {200, 85};
|
static const ImVec2 IMGUI_ANIMATION_PREVIEW_SETTINGS_CHILD_SIZE = {200, 85};
|
||||||
static const ImVec2 IMGUI_ANIMATION_PREVIEW_POSITION = {8, 135};
|
static const ImVec2 IMGUI_ANIMATION_PREVIEW_POSITION = {8, 135};
|
||||||
|
|
||||||
static const ImVec2 IMGUI_TIMELINE_ELEMENT_NAME_SIZE = {95, 20};
|
|
||||||
static const ImVec2 IMGUI_TIMELINE_ELEMENT_SPRITESHEET_ID_SIZE = {45, 20};
|
|
||||||
|
|
||||||
static const ImVec2 IMGUI_SPRITESHEET_EDITOR_SETTINGS_CHILD_SIZE = {200, 85};
|
static const ImVec2 IMGUI_SPRITESHEET_EDITOR_SETTINGS_CHILD_SIZE = {200, 85};
|
||||||
static const ImVec2 IMGUI_SPRITESHEET_EDITOR_SETTINGS_SIZE = {1280, 105};
|
static const ImVec2 IMGUI_SPRITESHEET_EDITOR_SETTINGS_SIZE = {1280, 105};
|
||||||
|
|
||||||
@@ -52,15 +51,13 @@ static const ImVec2 IMGUI_TIMELINE_VIEWER_SIZE = {0, 40};
|
|||||||
static const ImVec2 IMGUI_TIMELINE_ELEMENTS_TIMELINE_SIZE = {0, 40};
|
static const ImVec2 IMGUI_TIMELINE_ELEMENTS_TIMELINE_SIZE = {0, 40};
|
||||||
static const ImVec2 IMGUI_TIMELINE_FRAME_INDICES_SIZE = {0, 40};
|
static const ImVec2 IMGUI_TIMELINE_FRAME_INDICES_SIZE = {0, 40};
|
||||||
static const ImVec2 IMGUI_TIMELINE_ELEMENT_SIZE = {300, 40};
|
static const ImVec2 IMGUI_TIMELINE_ELEMENT_SIZE = {300, 40};
|
||||||
static const ImVec2 IMGUI_TIMELINE_SHIFT_ARROWS_SIZE = {64, 40};
|
static const ImVec2 IMGUI_TIMELINE_ELEMENT_NAME_SIZE = {150, 20};
|
||||||
|
static const ImVec2 IMGUI_TIMELINE_ELEMENT_SPRITESHEET_ID_SIZE = {60, 20};
|
||||||
|
|
||||||
static const ImVec2 IMGUI_SPRITESHEET_SIZE = {0, 150};
|
static const ImVec2 IMGUI_SPRITESHEET_SIZE = {0, 150};
|
||||||
static const ImVec2 IMGUI_SPRITESHEET_PREVIEW_SIZE = {100, 100};
|
static const ImVec2 IMGUI_SPRITESHEET_PREVIEW_SIZE = {100, 100};
|
||||||
static const ImVec2 IMGUI_ICON_SIZE = {16, 16};
|
|
||||||
static const ImVec2 IMGUI_ICON_SMALL_SIZE = {8, 8};
|
|
||||||
static const ImVec2 IMGUI_ICON_DUMMY_SIZE = {20, 16};
|
|
||||||
static const ImVec2 IMGUI_ICON_BUTTON_SIZE = {24, 24};
|
|
||||||
static const ImVec2 IMGUI_IMAGE_TARGET_SIZE = {125, 125};
|
static const ImVec2 IMGUI_IMAGE_TARGET_SIZE = {125, 125};
|
||||||
|
static const ImVec2 IMGUI_ICON_BUTTON_SIZE = {24, 24};
|
||||||
static const ImVec2 IMGUI_DUMMY_SIZE = {1, 1};
|
static const ImVec2 IMGUI_DUMMY_SIZE = {1, 1};
|
||||||
|
|
||||||
static const ImVec4 IMGUI_TIMELINE_HEADER_COLOR = {0.04, 0.04, 0.04, 1.0f};
|
static const ImVec4 IMGUI_TIMELINE_HEADER_COLOR = {0.04, 0.04, 0.04, 1.0f};
|
||||||
@@ -89,15 +86,6 @@ static const ImVec4 IMGUI_TIMELINE_LAYER_ACTIVE_COLOR = {1.000, 0.618, 0.324, 0.
|
|||||||
static const ImVec4 IMGUI_TIMELINE_NULL_ACTIVE_COLOR = {0.646, 0.971, 0.441, 0.75};
|
static const ImVec4 IMGUI_TIMELINE_NULL_ACTIVE_COLOR = {0.646, 0.971, 0.441, 0.75};
|
||||||
static const ImVec4 IMGUI_TIMELINE_TRIGGERS_ACTIVE_COLOR = {1.000, 0.618, 0.735, 0.75};
|
static const ImVec4 IMGUI_TIMELINE_TRIGGERS_ACTIVE_COLOR = {1.000, 0.618, 0.735, 0.75};
|
||||||
|
|
||||||
#define TOOL_COUNT (TOOL_CROP + 1)
|
|
||||||
enum ToolType
|
|
||||||
{
|
|
||||||
TOOL_PAN,
|
|
||||||
TOOL_MOVE,
|
|
||||||
TOOL_ROTATE,
|
|
||||||
TOOL_SCALE,
|
|
||||||
TOOL_CROP
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Imgui
|
struct Imgui
|
||||||
{
|
{
|
||||||
@@ -105,32 +93,34 @@ struct Imgui
|
|||||||
Resources* resources = NULL;
|
Resources* resources = NULL;
|
||||||
Input* input = NULL;
|
Input* input = NULL;
|
||||||
Anm2* anm2 = NULL;
|
Anm2* anm2 = NULL;
|
||||||
|
Anm2Reference* reference = NULL;
|
||||||
|
s32* animationID = NULL;
|
||||||
|
s32* spritesheetID = NULL;
|
||||||
Editor* editor = NULL;
|
Editor* editor = NULL;
|
||||||
Preview* preview = NULL;
|
Preview* preview = NULL;
|
||||||
|
Settings* settings = NULL;
|
||||||
|
Tool* tool = NULL;
|
||||||
SDL_Window* window = NULL;
|
SDL_Window* window = NULL;
|
||||||
SDL_GLContext* glContext = NULL;
|
SDL_GLContext* glContext = NULL;
|
||||||
Settings* settings = NULL;
|
bool isSwap = false;
|
||||||
s32 animationID = -1;
|
Anm2Reference swapReference;
|
||||||
s32 timelineElementID = -1;
|
|
||||||
s32 eventID = -1;
|
|
||||||
s32 spritesheetID = -1;
|
|
||||||
s32 timelineElementIndex = -1;
|
|
||||||
Anm2AnimationType animationType = ANM2_NONE;
|
|
||||||
ToolType tool = TOOL_PAN;
|
|
||||||
void* frameVector = NULL;
|
|
||||||
s32 frameIndex = -1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void imgui_init
|
void
|
||||||
|
imgui_init
|
||||||
(
|
(
|
||||||
Imgui* self,
|
Imgui* self,
|
||||||
Dialog* dialog,
|
Dialog* dialog,
|
||||||
Resources* resources,
|
Resources* resources,
|
||||||
Input* input,
|
Input* input,
|
||||||
Anm2* anm2,
|
Anm2* anm2,
|
||||||
|
Anm2Reference* reference,
|
||||||
|
s32* animationID,
|
||||||
|
s32* spritesheetID,
|
||||||
Editor* editor,
|
Editor* editor,
|
||||||
Preview* preview,
|
Preview* preview,
|
||||||
Settings* settings,
|
Settings* settings,
|
||||||
|
Tool* tool,
|
||||||
SDL_Window* window,
|
SDL_Window* window,
|
||||||
SDL_GLContext* glContext
|
SDL_GLContext* glContext
|
||||||
);
|
);
|
||||||
|
@@ -29,6 +29,19 @@ _mouse_tick(Mouse* self)
|
|||||||
self->oldPosition = self->position;
|
self->oldPosition = self->position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_keyboard_tick(Keyboard* self)
|
||||||
|
{
|
||||||
|
const bool* state;
|
||||||
|
|
||||||
|
memcpy(&self->previous, &self->current, sizeof(self->previous));
|
||||||
|
memset(&self->current, '\0', sizeof(self->current));
|
||||||
|
|
||||||
|
state = SDL_GetKeyboardState(NULL);
|
||||||
|
|
||||||
|
memcpy(&self->current, state, KEY_COUNT);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
mouse_press(Mouse* self, MouseType type)
|
mouse_press(Mouse* self, MouseType type)
|
||||||
{
|
{
|
||||||
@@ -47,8 +60,27 @@ mouse_release(Mouse* self, MouseType type)
|
|||||||
return (!self->current[type] && self->previous[type]);
|
return (!self->current[type] && self->previous[type]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
key_press(Keyboard* self, KeyType type)
|
||||||
|
{
|
||||||
|
return (self->current[type] && !self->previous[type]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
key_held(Keyboard* self, KeyType type)
|
||||||
|
{
|
||||||
|
return (self->current[type] && self->previous[type]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
key_release(Keyboard* self, KeyType type)
|
||||||
|
{
|
||||||
|
return (!self->current[type] && self->previous[type]);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
input_tick(Input* self)
|
input_tick(Input* self)
|
||||||
{
|
{
|
||||||
_mouse_tick(&self->mouse);
|
_mouse_tick(&self->mouse);
|
||||||
|
_keyboard_tick(&self->keyboard);
|
||||||
}
|
}
|
||||||
|
262
src/input.h
262
src/input.h
@@ -9,22 +9,267 @@ enum MouseType
|
|||||||
MOUSE_RIGHT
|
MOUSE_RIGHT
|
||||||
};
|
};
|
||||||
|
|
||||||
#define KEY_COUNT (KEY_DELETE + 1)
|
#define KEY_COUNT (255)
|
||||||
enum KeyType
|
enum KeyType
|
||||||
{
|
{
|
||||||
KEY_DELETE
|
KEY_UNKNOWN = 0,
|
||||||
|
KEY_UNKNOWN_TWO = 1,
|
||||||
|
KEY_UNKNOWN_THREE = 2,
|
||||||
|
KEY_UNKNOWN_FOUR = 3,
|
||||||
|
KEY_A = 4,
|
||||||
|
KEY_B = 5,
|
||||||
|
KEY_C = 6,
|
||||||
|
KEY_D = 7,
|
||||||
|
KEY_E = 8,
|
||||||
|
KEY_F = 9,
|
||||||
|
KEY_G = 10,
|
||||||
|
KEY_H = 11,
|
||||||
|
KEY_I = 12,
|
||||||
|
KEY_J = 13,
|
||||||
|
KEY_K = 14,
|
||||||
|
KEY_L = 15,
|
||||||
|
KEY_M = 16,
|
||||||
|
KEY_N = 17,
|
||||||
|
KEY_O = 18,
|
||||||
|
KEY_P = 19,
|
||||||
|
KEY_Q = 20,
|
||||||
|
KEY_R = 21,
|
||||||
|
KEY_S = 22,
|
||||||
|
KEY_T = 23,
|
||||||
|
KEY_U = 24,
|
||||||
|
KEY_V = 25,
|
||||||
|
KEY_W = 26,
|
||||||
|
KEY_X = 27,
|
||||||
|
KEY_Y = 28,
|
||||||
|
KEY_Z = 29,
|
||||||
|
KEY_1 = 30,
|
||||||
|
KEY_2 = 31,
|
||||||
|
KEY_3 = 32,
|
||||||
|
KEY_4 = 33,
|
||||||
|
KEY_5 = 34,
|
||||||
|
KEY_6 = 35,
|
||||||
|
KEY_7 = 36,
|
||||||
|
KEY_8 = 37,
|
||||||
|
KEY_9 = 38,
|
||||||
|
KEY_0 = 39,
|
||||||
|
KEY_RETURN = 40,
|
||||||
|
KEY_ESCAPE = 41,
|
||||||
|
KEY_BACKSPACE = 42,
|
||||||
|
KEY_TAB = 43,
|
||||||
|
KEY_SPACE = 44,
|
||||||
|
KEY_MINUS = 45,
|
||||||
|
KEY_EQUALS = 46,
|
||||||
|
KEY_LEFTBRACKET = 47,
|
||||||
|
KEY_RIGHTBRACKET = 48,
|
||||||
|
KEY_BACKSLASH = 49,
|
||||||
|
KEY_NONUSHASH = 50,
|
||||||
|
KEY_SEMICOLON = 51,
|
||||||
|
KEY_APOSTROPHE = 52,
|
||||||
|
KEY_GRAVE = 53,
|
||||||
|
KEY_COMMA = 54,
|
||||||
|
KEY_PERIOD = 55,
|
||||||
|
KEY_SLASH = 56,
|
||||||
|
KEY_CAPSLOCK = 57,
|
||||||
|
KEY_F1 = 58,
|
||||||
|
KEY_F2 = 59,
|
||||||
|
KEY_F3 = 60,
|
||||||
|
KEY_F4 = 61,
|
||||||
|
KEY_F5 = 62,
|
||||||
|
KEY_F6 = 63,
|
||||||
|
KEY_F7 = 64,
|
||||||
|
KEY_F8 = 65,
|
||||||
|
KEY_F9 = 66,
|
||||||
|
KEY_F10 = 67,
|
||||||
|
KEY_F11 = 68,
|
||||||
|
KEY_F12 = 69,
|
||||||
|
KEY_PRINTSCREEN = 70,
|
||||||
|
KEY_SCROLLLOCK = 71,
|
||||||
|
KEY_PAUSE = 72,
|
||||||
|
KEY_INSERT = 73,
|
||||||
|
KEY_HOME = 74,
|
||||||
|
KEY_PAGEUP = 75,
|
||||||
|
KEY_DELETE = 76,
|
||||||
|
KEY_END = 77,
|
||||||
|
KEY_PAGEDOWN = 78,
|
||||||
|
KEY_RIGHT = 79,
|
||||||
|
KEY_LEFT = 80,
|
||||||
|
KEY_DOWN = 81,
|
||||||
|
KEY_UP = 82,
|
||||||
|
KEY_NUMLOCKCLEAR = 83,
|
||||||
|
KEY_KP_DIVIDE = 84,
|
||||||
|
KEY_KP_MULTIPLY = 85,
|
||||||
|
KEY_KP_MINUS = 86,
|
||||||
|
KEY_KP_PLUS = 87,
|
||||||
|
KEY_KP_ENTER = 88,
|
||||||
|
KEY_KP_1 = 89,
|
||||||
|
KEY_KP_2 = 90,
|
||||||
|
KEY_KP_3 = 91,
|
||||||
|
KEY_KP_4 = 92,
|
||||||
|
KEY_KP_5 = 93,
|
||||||
|
KEY_KP_6 = 94,
|
||||||
|
KEY_KP_7 = 95,
|
||||||
|
KEY_KP_8 = 96,
|
||||||
|
KEY_KP_9 = 97,
|
||||||
|
KEY_KP_0 = 98,
|
||||||
|
KEY_KP_PERIOD = 99,
|
||||||
|
KEY_NONUSBACKSLASH = 100,
|
||||||
|
KEY_APPLICATION = 101,
|
||||||
|
KEY_POWER = 102,
|
||||||
|
KEY_KP_EQUALS = 103,
|
||||||
|
KEY_F13 = 104,
|
||||||
|
KEY_F14 = 105,
|
||||||
|
KEY_F15 = 106,
|
||||||
|
KEY_F16 = 107,
|
||||||
|
KEY_F17 = 108,
|
||||||
|
KEY_F18 = 109,
|
||||||
|
KEY_F19 = 110,
|
||||||
|
KEY_F20 = 111,
|
||||||
|
KEY_F21 = 112,
|
||||||
|
KEY_F22 = 113,
|
||||||
|
KEY_F23 = 114,
|
||||||
|
KEY_F24 = 115,
|
||||||
|
KEY_EXECUTE = 116,
|
||||||
|
KEY_HELP = 117,
|
||||||
|
KEY_MENU = 118,
|
||||||
|
KEY_SELECT = 119,
|
||||||
|
KEY_STOP = 120,
|
||||||
|
KEY_AGAIN = 121,
|
||||||
|
KEY_UNDO = 122,
|
||||||
|
KEY_CUT = 123,
|
||||||
|
KEY_COPY = 124,
|
||||||
|
KEY_PASTE = 125,
|
||||||
|
KEY_FIND = 126,
|
||||||
|
KEY_MUTE = 127,
|
||||||
|
KEY_VOLUMEUP = 128,
|
||||||
|
KEY_VOLUMEDOWN = 129,
|
||||||
|
KEY_LOCKINGCAPSLOCK = 130,
|
||||||
|
KEY_LOCKINGNUMLOCK = 131,
|
||||||
|
KEY_LOCKINGSCROLLLOCK = 132,
|
||||||
|
KEY_KP_COMMA = 133,
|
||||||
|
KEY_KP_EQUALSAS400 = 134,
|
||||||
|
KEY_INTERNATIONAL1 = 135,
|
||||||
|
KEY_INTERNATIONAL2 = 136,
|
||||||
|
KEY_INTERNATIONAL3 = 137,
|
||||||
|
KEY_INTERNATIONAL4 = 138,
|
||||||
|
KEY_INTERNATIONAL5 = 139,
|
||||||
|
KEY_INTERNATIONAL6 = 140,
|
||||||
|
KEY_INTERNATIONAL7 = 141,
|
||||||
|
KEY_INTERNATIONAL8 = 142,
|
||||||
|
KEY_INTERNATIONAL9 = 143,
|
||||||
|
KEY_LANG1 = 144,
|
||||||
|
KEY_LANG2 = 145,
|
||||||
|
KEY_LANG3 = 146,
|
||||||
|
KEY_LANG4 = 147,
|
||||||
|
KEY_LANG5 = 148,
|
||||||
|
KEY_LANG6 = 149,
|
||||||
|
KEY_LANG7 = 150,
|
||||||
|
KEY_LANG8 = 151,
|
||||||
|
KEY_LANG9 = 152,
|
||||||
|
KEY_ALTERASE = 153,
|
||||||
|
KEY_SYSREQ = 154,
|
||||||
|
KEY_CANCEL = 155,
|
||||||
|
KEY_CLEAR = 156,
|
||||||
|
KEY_PRIOR = 157,
|
||||||
|
KEY_RETURN2 = 158,
|
||||||
|
KEY_SEPARATOR = 159,
|
||||||
|
KEY_OUT = 160,
|
||||||
|
KEY_OPER = 161,
|
||||||
|
KEY_CLEARAGAIN = 162,
|
||||||
|
KEY_CRSEL = 163,
|
||||||
|
KEY_EXSEL = 164,
|
||||||
|
KEY_KP_00 = 176,
|
||||||
|
KEY_KP_000 = 177,
|
||||||
|
KEY_THOUSANDSSEPARATOR = 178,
|
||||||
|
KEY_DECIMALSEPARATOR = 179,
|
||||||
|
KEY_CURRENCYUNIT = 180,
|
||||||
|
KEY_CURRENCYSUBUNIT = 181,
|
||||||
|
KEY_KP_LEFTPAREN = 182,
|
||||||
|
KEY_KP_RIGHTPAREN = 183,
|
||||||
|
KEY_KP_LEFTBRACE = 184,
|
||||||
|
KEY_KP_RIGHTBRACE = 185,
|
||||||
|
KEY_KP_TAB = 186,
|
||||||
|
KEY_KP_BACKSPACE = 187,
|
||||||
|
KEY_KP_A = 188,
|
||||||
|
KEY_KP_B = 189,
|
||||||
|
KEY_KP_C = 190,
|
||||||
|
KEY_KP_D = 191,
|
||||||
|
KEY_KP_E = 192,
|
||||||
|
KEY_KP_F = 193,
|
||||||
|
KEY_KP_XOR = 194,
|
||||||
|
KEY_KP_POWER = 195,
|
||||||
|
KEY_KP_PERCENT = 196,
|
||||||
|
KEY_KP_LESS = 197,
|
||||||
|
KEY_KP_GREATER = 198,
|
||||||
|
KEY_KP_AMPERSAND = 199,
|
||||||
|
KEY_KP_DBLAMPERSAND = 200,
|
||||||
|
KEY_KP_VERTICALBAR = 201,
|
||||||
|
KEY_KP_DBLVERTICALBAR = 202,
|
||||||
|
KEY_KP_COLON = 203,
|
||||||
|
KEY_KP_HASH = 204,
|
||||||
|
KEY_KP_SPACE = 205,
|
||||||
|
KEY_KP_AT = 206,
|
||||||
|
KEY_KP_EXCLAM = 207,
|
||||||
|
KEY_KP_MEMSTORE = 208,
|
||||||
|
KEY_KP_MEMRECALL = 209,
|
||||||
|
KEY_KP_MEMCLEAR = 210,
|
||||||
|
KEY_KP_MEMADD = 211,
|
||||||
|
KEY_KP_MEMSUBTRACT = 212,
|
||||||
|
KEY_KP_MEMMULTIPLY = 213,
|
||||||
|
KEY_KP_MEMDIVIDE = 214,
|
||||||
|
KEY_KP_PLUSMINUS = 215,
|
||||||
|
KEY_KP_CLEAR = 216,
|
||||||
|
KEY_KP_CLEARENTRY = 217,
|
||||||
|
KEY_KP_BINARY = 218,
|
||||||
|
KEY_KP_OCTAL = 219,
|
||||||
|
KEY_KP_DECIMAL = 220,
|
||||||
|
KEY_KP_HEXADECIMAL = 221,
|
||||||
|
KEY_LCTRL = 224,
|
||||||
|
KEY_LSHIFT = 225,
|
||||||
|
KEY_LALT = 226,
|
||||||
|
KEY_LGUI = 227,
|
||||||
|
KEY_RCTRL = 228,
|
||||||
|
KEY_RSHIFT = 229,
|
||||||
|
KEY_RALT = 230,
|
||||||
|
KEY_RGUI = 231
|
||||||
};
|
};
|
||||||
|
|
||||||
#define INPUT_COUNT (INPUT_MOUSE_CLICK + 1)
|
#define INPUT_COUNT (INPUT_ZOOM_OUT + 1)
|
||||||
enum InputType
|
enum InputType
|
||||||
{
|
{
|
||||||
INPUT_MOUSE_CLICK
|
INPUT_PAN,
|
||||||
|
INPUT_MOVE,
|
||||||
|
INPUT_SCALE,
|
||||||
|
INPUT_CROP,
|
||||||
|
INPUT_LEFT,
|
||||||
|
INPUT_RIGHT,
|
||||||
|
INPUT_UP,
|
||||||
|
INPUT_DOWN,
|
||||||
|
INPUT_ROTATE_LEFT,
|
||||||
|
INPUT_ROTATE_RIGHT,
|
||||||
|
INPUT_ZOOM_IN,
|
||||||
|
INPUT_ZOOM_OUT
|
||||||
|
};
|
||||||
|
|
||||||
|
static const KeyType INPUT_KEYS[INPUT_COUNT]
|
||||||
|
{
|
||||||
|
KEY_SPACE,
|
||||||
|
KEY_T,
|
||||||
|
KEY_S,
|
||||||
|
KEY_C,
|
||||||
|
KEY_LEFT,
|
||||||
|
KEY_RIGHT,
|
||||||
|
KEY_UP,
|
||||||
|
KEY_DOWN,
|
||||||
|
KEY_Q,
|
||||||
|
KEY_W,
|
||||||
|
KEY_1,
|
||||||
|
KEY_2
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Keyboard
|
struct Keyboard
|
||||||
{
|
{
|
||||||
bool current[MOUSE_COUNT];
|
bool current[KEY_COUNT];
|
||||||
bool previous[MOUSE_COUNT];
|
bool previous[KEY_COUNT];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Mouse
|
struct Mouse
|
||||||
@@ -39,11 +284,14 @@ struct Mouse
|
|||||||
|
|
||||||
struct Input
|
struct Input
|
||||||
{
|
{
|
||||||
Keyboard keyboard;
|
|
||||||
Mouse mouse;
|
Mouse mouse;
|
||||||
|
Keyboard keyboard;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool mouse_press(Mouse* self, MouseType type);
|
bool mouse_press(Mouse* self, MouseType type);
|
||||||
bool mouse_held(Mouse* self, MouseType type);
|
bool mouse_held(Mouse* self, MouseType type);
|
||||||
bool mouse_release(Mouse* self, MouseType type);
|
bool mouse_release(Mouse* self, MouseType type);
|
||||||
|
bool key_press(Keyboard* self, KeyType type);
|
||||||
|
bool key_held(Keyboard* self, KeyType type);
|
||||||
|
bool key_release(Keyboard* self, KeyType type);
|
||||||
void input_tick(Input* self);
|
void input_tick(Input* self);
|
107
src/preview.cpp
107
src/preview.cpp
@@ -1,7 +1,7 @@
|
|||||||
#include "preview.h"
|
#include "preview.h"
|
||||||
|
|
||||||
static void _preview_axis_set(Preview* self);
|
static void _preview_axis_set(Preview* self);
|
||||||
static void _preview_grid_set(Preview* self);
|
static s32 _preview_grid_set(Preview* self);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_preview_axis_set(Preview* self)
|
_preview_axis_set(Preview* self)
|
||||||
@@ -16,13 +16,14 @@ _preview_axis_set(Preview* self)
|
|||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/* Sets and returns the grid's vertices */
|
||||||
|
static s32
|
||||||
_preview_grid_set(Preview* self)
|
_preview_grid_set(Preview* self)
|
||||||
{
|
{
|
||||||
std::vector<f32> vertices;
|
std::vector<f32> vertices;
|
||||||
|
|
||||||
s32 verticalLineCount = PREVIEW_SIZE.x / MIN(self->settings->previewGridSizeX, PREVIEW_GRID_MIN);
|
s32 verticalLineCount = (s32)(PREVIEW_SIZE.x / MIN(self->settings->previewGridSizeX, PREVIEW_GRID_MIN));
|
||||||
s32 horizontalLineCount = PREVIEW_SIZE.y / MIN(self->settings->previewGridSizeY, PREVIEW_GRID_MIN);
|
s32 horizontalLineCount = (s32)(PREVIEW_SIZE.y / MIN(self->settings->previewGridSizeY, PREVIEW_GRID_MIN));
|
||||||
|
|
||||||
/* Vertical */
|
/* Vertical */
|
||||||
for (s32 i = 0; i <= verticalLineCount; i++)
|
for (s32 i = 0; i <= verticalLineCount; i++)
|
||||||
@@ -48,22 +49,23 @@ _preview_grid_set(Preview* self)
|
|||||||
vertices.push_back(normY);
|
vertices.push_back(normY);
|
||||||
}
|
}
|
||||||
|
|
||||||
self->gridVertexCount = (s32)vertices.size();
|
|
||||||
|
|
||||||
glBindVertexArray(self->gridVAO);
|
glBindVertexArray(self->gridVAO);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, self->gridVBO);
|
glBindBuffer(GL_ARRAY_BUFFER, self->gridVBO);
|
||||||
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(f32), vertices.data(), GL_DYNAMIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(f32), vertices.data(), GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(f32), (void*)0);
|
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(f32), (void*)0);
|
||||||
|
|
||||||
|
return (s32)vertices.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
preview_init(Preview* self, Anm2* anm2, Resources* resources, Input* input, Settings* settings)
|
preview_init(Preview* self, Anm2* anm2, Anm2Reference* reference, s32* animationID, Resources* resources, Settings* settings)
|
||||||
{
|
{
|
||||||
self->anm2 = anm2;
|
self->anm2 = anm2;
|
||||||
|
self->reference = reference;
|
||||||
|
self->animationID = animationID;
|
||||||
self->resources = resources;
|
self->resources = resources;
|
||||||
self->input = input;
|
|
||||||
self->settings = settings;
|
self->settings = settings;
|
||||||
|
|
||||||
/* Framebuffer + texture */
|
/* Framebuffer + texture */
|
||||||
@@ -138,13 +140,10 @@ preview_tick(Preview* self)
|
|||||||
{
|
{
|
||||||
self->settings->previewZoom = CLAMP(self->settings->previewZoom, PREVIEW_ZOOM_MIN, PREVIEW_ZOOM_MAX);
|
self->settings->previewZoom = CLAMP(self->settings->previewZoom, PREVIEW_ZOOM_MIN, PREVIEW_ZOOM_MAX);
|
||||||
|
|
||||||
self->oldGridSize = glm::vec2(self->settings->previewGridSizeX, self->settings->previewGridSizeY);
|
Anm2Animation* animation = anm2_animation_from_id(self->anm2, *self->animationID);
|
||||||
self->oldGridOffset = glm::vec2(self->settings->previewGridOffsetX, self->settings->previewGridOffsetY);
|
|
||||||
|
|
||||||
if (self->animationID > -1)
|
if (animation)
|
||||||
{
|
{
|
||||||
Anm2Animation* animation = &self->anm2->animations[self->animationID];
|
|
||||||
|
|
||||||
if (self->isPlaying)
|
if (self->isPlaying)
|
||||||
{
|
{
|
||||||
self->time += (f32)self->anm2->fps / TICK_RATE;
|
self->time += (f32)self->anm2->fps / TICK_RATE;
|
||||||
@@ -183,12 +182,18 @@ preview_draw(Preview* self)
|
|||||||
/* Grid */
|
/* Grid */
|
||||||
if (self->settings->previewIsGrid)
|
if (self->settings->previewIsGrid)
|
||||||
{
|
{
|
||||||
if
|
static ivec2 previousGridSize = {-1, -1};
|
||||||
(
|
static ivec2 previousGridOffset = {-1, -1};
|
||||||
(ivec2(self->settings->previewGridSizeX, self->settings->previewGridSizeY) != self->oldGridSize) ||
|
static s32 gridVertexCount = -1;
|
||||||
(ivec2(self->settings->previewGridOffsetX, self->settings->previewGridOffsetY) != self->oldGridOffset)
|
ivec2 gridSize = ivec2(self->settings->previewGridSizeX, self->settings->previewGridSizeY);
|
||||||
)
|
ivec2 gridOffset = ivec2(self->settings->previewGridOffsetX, self->settings->previewGridOffsetY);
|
||||||
_preview_grid_set(self);
|
|
||||||
|
if (previousGridSize != gridSize || previousGridOffset != gridOffset)
|
||||||
|
{
|
||||||
|
gridVertexCount = _preview_grid_set(self);
|
||||||
|
previousGridSize = gridSize;
|
||||||
|
previousGridOffset = gridOffset;
|
||||||
|
}
|
||||||
|
|
||||||
glUseProgram(shaderLine);
|
glUseProgram(shaderLine);
|
||||||
glBindVertexArray(self->gridVAO);
|
glBindVertexArray(self->gridVAO);
|
||||||
@@ -200,7 +205,7 @@ preview_draw(Preview* self)
|
|||||||
self->settings->previewGridColorR, self->settings->previewGridColorG, self->settings->previewGridColorB, self->settings->previewGridColorA
|
self->settings->previewGridColorR, self->settings->previewGridColorG, self->settings->previewGridColorB, self->settings->previewGridColorA
|
||||||
);
|
);
|
||||||
|
|
||||||
glDrawArrays(GL_LINES, 0, self->gridVertexCount);
|
glDrawArrays(GL_LINES, 0, gridVertexCount);
|
||||||
|
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
@@ -230,33 +235,32 @@ preview_draw(Preview* self)
|
|||||||
|
|
||||||
glDrawArrays(GL_LINES, 2, 2);
|
glDrawArrays(GL_LINES, 2, 2);
|
||||||
|
|
||||||
|
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Animation */
|
Anm2Animation* animation = anm2_animation_from_id(self->anm2, *self->animationID);
|
||||||
if (self->animationID > -1)
|
|
||||||
{
|
|
||||||
Anm2Frame rootFrame = Anm2Frame{};
|
|
||||||
Anm2Animation* animation = &self->anm2->animations[self->animationID];
|
|
||||||
bool isRootFrame = anm2_frame_from_time(self->anm2, animation, &rootFrame, ANM2_ROOT_ANIMATION, 0, self->time);
|
|
||||||
|
|
||||||
/* Layers (Reversed) */
|
/* Animation */
|
||||||
|
if (animation)
|
||||||
|
{
|
||||||
|
Anm2Frame rootFrame;
|
||||||
|
anm2_frame_from_time(self->anm2, &rootFrame, Anm2Reference{ANM2_ROOT, 0, 0}, *self->animationID, self->time);
|
||||||
|
|
||||||
|
/* Layers */
|
||||||
for (auto & [id, layerAnimation] : animation->layerAnimations)
|
for (auto & [id, layerAnimation] : animation->layerAnimations)
|
||||||
{
|
{
|
||||||
if (!layerAnimation.isVisible || layerAnimation.frames.size() <= 0)
|
if (!layerAnimation.isVisible || layerAnimation.frames.size() <= 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Anm2Layer* layer = &self->anm2->layers[id];
|
Anm2Frame frame;
|
||||||
Anm2Frame frame = layerAnimation.frames[0];
|
|
||||||
|
|
||||||
anm2_frame_from_time(self->anm2, animation, &frame, ANM2_LAYER_ANIMATION, id, self->time);
|
anm2_frame_from_time(self->anm2, &frame, Anm2Reference{ANM2_LAYER, id, 0}, *self->animationID, self->time);
|
||||||
|
|
||||||
if (!frame.isVisible)
|
if (!frame.isVisible)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Texture* texture = &self->resources->textures[layer->spritesheetID];
|
Texture* texture = &self->resources->textures[self->anm2->layers[id].spritesheetID];
|
||||||
|
|
||||||
if (texture->isInvalid)
|
if (texture->isInvalid)
|
||||||
continue;
|
continue;
|
||||||
@@ -264,7 +268,7 @@ preview_draw(Preview* self)
|
|||||||
glm::mat4 layerTransform = previewTransform;
|
glm::mat4 layerTransform = previewTransform;
|
||||||
|
|
||||||
glm::vec2 position = self->settings->previewIsRootTransform ? (frame.position + rootFrame.position) : frame.position;
|
glm::vec2 position = self->settings->previewIsRootTransform ? (frame.position + rootFrame.position) : frame.position;
|
||||||
glm::vec2 scale = self->settings->previewIsRootTransform ? (frame.scale / 100.0f) * (rootFrame.scale / 100.0f) : (frame.scale / 100.0f);
|
glm::vec2 scale = frame.scale / 100.0f;
|
||||||
glm::vec2 ndcPos = position / (PREVIEW_SIZE / 2.0f);
|
glm::vec2 ndcPos = position / (PREVIEW_SIZE / 2.0f);
|
||||||
glm::vec2 ndcPivotOffset = (frame.pivot * scale) / (PREVIEW_SIZE / 2.0f);
|
glm::vec2 ndcPivotOffset = (frame.pivot * scale) / (PREVIEW_SIZE / 2.0f);
|
||||||
glm::vec2 ndcScale = (frame.size * scale) / (PREVIEW_SIZE / 2.0f);
|
glm::vec2 ndcScale = (frame.size * scale) / (PREVIEW_SIZE / 2.0f);
|
||||||
@@ -276,7 +280,6 @@ preview_draw(Preview* self)
|
|||||||
layerTransform = glm::translate(layerTransform, glm::vec3(-ndcPivotOffset, 0.0f));
|
layerTransform = glm::translate(layerTransform, glm::vec3(-ndcPivotOffset, 0.0f));
|
||||||
layerTransform = glm::scale(layerTransform, glm::vec3(ndcScale, 1.0f));
|
layerTransform = glm::scale(layerTransform, glm::vec3(ndcScale, 1.0f));
|
||||||
|
|
||||||
|
|
||||||
glm::vec2 uvMin = frame.crop / glm::vec2(texture->size);
|
glm::vec2 uvMin = frame.crop / glm::vec2(texture->size);
|
||||||
glm::vec2 uvMax = (frame.crop + frame.size) / glm::vec2(texture->size);
|
glm::vec2 uvMax = (frame.crop + frame.size) / glm::vec2(texture->size);
|
||||||
|
|
||||||
@@ -305,17 +308,13 @@ preview_draw(Preview* self)
|
|||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Root */
|
if (animation->rootAnimation.isVisible && rootFrame.isVisible)
|
||||||
if
|
|
||||||
(isRootFrame && animation->rootAnimation.isVisible && rootFrame.isVisible)
|
|
||||||
{
|
{
|
||||||
glm::mat4 rootTransform = previewTransform;
|
glm::mat4 rootTransform = previewTransform;
|
||||||
glm::vec2 ndcPos = (rootFrame.position - (ATLAS_SIZES[TEXTURE_TARGET] / 2.0f)) / (PREVIEW_SIZE / 2.0f);
|
glm::vec2 ndcPos = (rootFrame.position - (PREVIEW_TARGET_SIZE / 2.0f)) / (PREVIEW_SIZE / 2.0f);
|
||||||
glm::vec2 ndcScale = ATLAS_SIZES[TEXTURE_TARGET] / (PREVIEW_SIZE / 2.0f);
|
glm::vec2 ndcScale = PREVIEW_TARGET_SIZE / (PREVIEW_SIZE / 2.0f);
|
||||||
glm::vec2 ndcPivot = (-ATLAS_SIZES[TEXTURE_TARGET] / 2.0f) / (PREVIEW_SIZE / 2.0f);
|
|
||||||
|
|
||||||
rootTransform = glm::translate(rootTransform, glm::vec3(ndcPos, 0.0f));
|
rootTransform = glm::translate(rootTransform, glm::vec3(ndcPos, 0.0f));
|
||||||
rootTransform = glm::rotate(rootTransform, glm::radians(rootFrame.rotation), glm::vec3(0, 0, 1));
|
|
||||||
rootTransform = glm::scale(rootTransform, glm::vec3(ndcScale, 1.0f));
|
rootTransform = glm::scale(rootTransform, glm::vec3(ndcScale, 1.0f));
|
||||||
|
|
||||||
f32 vertices[] = ATLAS_UV_VERTICES(TEXTURE_TARGET);
|
f32 vertices[] = ATLAS_UV_VERTICES(TEXTURE_TARGET);
|
||||||
@@ -346,17 +345,15 @@ preview_draw(Preview* self)
|
|||||||
/* Pivots */
|
/* Pivots */
|
||||||
if (self->settings->previewIsShowPivot)
|
if (self->settings->previewIsShowPivot)
|
||||||
{
|
{
|
||||||
for (auto it = animation->layerAnimations.rbegin(); it != animation->layerAnimations.rend(); it++)
|
/* Layers (Reversed) */
|
||||||
|
for (auto & [id, layerAnimation] : animation->layerAnimations)
|
||||||
{
|
{
|
||||||
s32 id = it->first;
|
|
||||||
Anm2LayerAnimation layerAnimation = it->second;
|
|
||||||
|
|
||||||
if (!layerAnimation.isVisible || layerAnimation.frames.size() <= 0)
|
if (!layerAnimation.isVisible || layerAnimation.frames.size() <= 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Anm2Frame frame = layerAnimation.frames[0];
|
Anm2Frame frame;
|
||||||
|
|
||||||
anm2_frame_from_time(self->anm2, animation, &frame, ANM2_LAYER_ANIMATION, id, self->time);
|
anm2_frame_from_time(self->anm2, &frame, Anm2Reference{ANM2_LAYER, id, 0}, *self->animationID, self->time);
|
||||||
|
|
||||||
if (!frame.isVisible)
|
if (!frame.isVisible)
|
||||||
continue;
|
continue;
|
||||||
@@ -365,8 +362,8 @@ preview_draw(Preview* self)
|
|||||||
|
|
||||||
glm::vec2 position = self->settings->previewIsRootTransform ? (frame.position + rootFrame.position) : frame.position;
|
glm::vec2 position = self->settings->previewIsRootTransform ? (frame.position + rootFrame.position) : frame.position;
|
||||||
|
|
||||||
glm::vec2 ndcPos = (position - (ATLAS_SIZES[TEXTURE_PIVOT] / 2.0f)) / (PREVIEW_SIZE / 2.0f);
|
glm::vec2 ndcPos = (position - (PREVIEW_PIVOT_SIZE / 2.0f)) / (PREVIEW_SIZE / 2.0f);
|
||||||
glm::vec2 ndcScale = ATLAS_SIZES[TEXTURE_PIVOT] / (PREVIEW_SIZE / 2.0f);
|
glm::vec2 ndcScale = PREVIEW_PIVOT_SIZE / (PREVIEW_SIZE / 2.0f);
|
||||||
|
|
||||||
pivotTransform = glm::translate(pivotTransform, glm::vec3(ndcPos, 0.0f));
|
pivotTransform = glm::translate(pivotTransform, glm::vec3(ndcPos, 0.0f));
|
||||||
pivotTransform = glm::scale(pivotTransform, glm::vec3(ndcScale, 1.0f));
|
pivotTransform = glm::scale(pivotTransform, glm::vec3(ndcScale, 1.0f));
|
||||||
@@ -403,21 +400,19 @@ preview_draw(Preview* self)
|
|||||||
if (!nullAnimation.isVisible || nullAnimation.frames.size() <= 0)
|
if (!nullAnimation.isVisible || nullAnimation.frames.size() <= 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Anm2Frame frame = nullAnimation.frames[0];
|
Anm2Frame frame;
|
||||||
|
|
||||||
anm2_frame_from_time(self->anm2, animation, &frame, ANM2_NULL_ANIMATION, id, self->time);
|
anm2_frame_from_time(self->anm2, &frame, Anm2Reference{ANM2_NULL, id, 0}, *self->animationID, self->time);
|
||||||
|
|
||||||
if (!frame.isVisible)
|
if (!frame.isVisible)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Anm2Null* null = NULL;
|
Anm2Null* null = &self->anm2->nulls[id];
|
||||||
|
|
||||||
null = &self->anm2->nulls[id];
|
|
||||||
|
|
||||||
glm::mat4 nullTransform = previewTransform;
|
glm::mat4 nullTransform = previewTransform;
|
||||||
|
|
||||||
TextureType textureType = null->isShowRect ? TEXTURE_SQUARE : TEXTURE_TARGET;
|
TextureType textureType = null->isShowRect ? TEXTURE_SQUARE : TEXTURE_TARGET;
|
||||||
glm::vec2 size = null->isShowRect ? PREVIEW_POINT_SIZE : ATLAS_SIZES[TEXTURE_TARGET];
|
glm::vec2 size = null->isShowRect ? PREVIEW_POINT_SIZE : PREVIEW_TARGET_SIZE;
|
||||||
glm::vec2 pos = self->settings->previewIsRootTransform ? frame.position + (rootFrame.position) - (size / 2.0f) : frame.position - (size / 2.0f);
|
glm::vec2 pos = self->settings->previewIsRootTransform ? frame.position + (rootFrame.position) - (size / 2.0f) : frame.position - (size / 2.0f);
|
||||||
|
|
||||||
glm::vec2 ndcPos = pos / (PREVIEW_SIZE / 2.0f);
|
glm::vec2 ndcPos = pos / (PREVIEW_SIZE / 2.0f);
|
||||||
@@ -477,8 +472,6 @@ preview_draw(Preview* self)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glUseProgram(0);
|
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -15,6 +15,9 @@ static const vec2 PREVIEW_CENTER = {0, 0};
|
|||||||
#define PREVIEW_GRID_MAX 1000
|
#define PREVIEW_GRID_MAX 1000
|
||||||
#define PREVIEW_GRID_OFFSET_MIN 0
|
#define PREVIEW_GRID_OFFSET_MIN 0
|
||||||
#define PREVIEW_GRID_OFFSET_MAX 100
|
#define PREVIEW_GRID_OFFSET_MAX 100
|
||||||
|
#define PREVIEW_MOVE_STEP 1
|
||||||
|
#define PREVIEW_ROTATE_STEP 1
|
||||||
|
#define PREVIEW_SCALE_STEP 1
|
||||||
|
|
||||||
static const f32 PREVIEW_AXIS_VERTICES[] =
|
static const f32 PREVIEW_AXIS_VERTICES[] =
|
||||||
{
|
{
|
||||||
@@ -26,16 +29,20 @@ static const f32 PREVIEW_AXIS_VERTICES[] =
|
|||||||
|
|
||||||
static const vec2 PREVIEW_NULL_RECT_SIZE = {100, 100};
|
static const vec2 PREVIEW_NULL_RECT_SIZE = {100, 100};
|
||||||
static const vec2 PREVIEW_POINT_SIZE = {2, 2};
|
static const vec2 PREVIEW_POINT_SIZE = {2, 2};
|
||||||
|
static const vec2 PREVIEW_PIVOT_SIZE = {4, 4};
|
||||||
static const vec4 PREVIEW_ROOT_TINT = COLOR_GREEN;
|
static const vec4 PREVIEW_ROOT_TINT = COLOR_GREEN;
|
||||||
static const vec4 PREVIEW_NULL_TINT = COLOR_BLUE;
|
static const vec4 PREVIEW_NULL_TINT = COLOR_BLUE;
|
||||||
static const vec4 PREVIEW_PIVOT_TINT = COLOR_RED;
|
static const vec4 PREVIEW_PIVOT_TINT = COLOR_RED;
|
||||||
|
static const vec2 PREVIEW_TARGET_SIZE = {16, 16};
|
||||||
|
|
||||||
struct Preview
|
struct Preview
|
||||||
{
|
{
|
||||||
Anm2* anm2 = NULL;
|
Anm2* anm2 = NULL;
|
||||||
|
Anm2Reference* reference = NULL;
|
||||||
Input* input = NULL;
|
Input* input = NULL;
|
||||||
Resources* resources = NULL;
|
Resources* resources = NULL;
|
||||||
Settings* settings = NULL;
|
Settings* settings = NULL;
|
||||||
|
s32* animationID = NULL;
|
||||||
GLuint axisVAO;
|
GLuint axisVAO;
|
||||||
GLuint axisVBO;
|
GLuint axisVBO;
|
||||||
GLuint fbo;
|
GLuint fbo;
|
||||||
@@ -50,14 +57,9 @@ struct Preview
|
|||||||
GLuint textureVBO;
|
GLuint textureVBO;
|
||||||
bool isPlaying = false;
|
bool isPlaying = false;
|
||||||
f32 time = 0;
|
f32 time = 0;
|
||||||
ivec2 oldGridOffset = {-1, -1};
|
|
||||||
ivec2 oldGridSize = {-1, -1};
|
|
||||||
ivec2 viewport = PREVIEW_SIZE;
|
|
||||||
s32 animationID = -1;
|
|
||||||
s32 gridVertexCount = -1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void preview_init(Preview* self, Anm2* anm2, Resources* resources, Input* input, Settings* settings);
|
void preview_init(Preview* self, Anm2* anm2, Anm2Reference* reference, s32* animationID, Resources* resources, Settings* settings);
|
||||||
void preview_draw(Preview* self);
|
void preview_draw(Preview* self);
|
||||||
void preview_tick(Preview* self);
|
void preview_tick(Preview* self);
|
||||||
void preview_free(Preview* self);
|
void preview_free(Preview* self);
|
||||||
|
@@ -52,6 +52,7 @@ enum SettingsItem
|
|||||||
SETTINGS_PREVIEW_BACKGROUND_COLOR_B,
|
SETTINGS_PREVIEW_BACKGROUND_COLOR_B,
|
||||||
SETTINGS_PREVIEW_BACKGROUND_COLOR_A,
|
SETTINGS_PREVIEW_BACKGROUND_COLOR_A,
|
||||||
SETTINGS_EDITOR_IS_GRID,
|
SETTINGS_EDITOR_IS_GRID,
|
||||||
|
SETTINGS_EDITOR_IS_GRID_SNAP,
|
||||||
SETTINGS_EDITOR_IS_BORDER,
|
SETTINGS_EDITOR_IS_BORDER,
|
||||||
SETTINGS_EDITOR_PAN_X,
|
SETTINGS_EDITOR_PAN_X,
|
||||||
SETTINGS_EDITOR_PAN_Y,
|
SETTINGS_EDITOR_PAN_Y,
|
||||||
@@ -98,6 +99,7 @@ struct Settings
|
|||||||
f32 previewBackgroundColorB = 0.286f;
|
f32 previewBackgroundColorB = 0.286f;
|
||||||
f32 previewBackgroundColorA = 1.0f;
|
f32 previewBackgroundColorA = 1.0f;
|
||||||
bool editorIsGrid = true;
|
bool editorIsGrid = true;
|
||||||
|
bool editorIsGridSnap = true;
|
||||||
bool editorIsBorder = true;
|
bool editorIsBorder = true;
|
||||||
f32 editorPanX = 0.0f;
|
f32 editorPanX = 0.0f;
|
||||||
f32 editorPanY = 0.0f;
|
f32 editorPanY = 0.0f;
|
||||||
@@ -144,6 +146,7 @@ static const SettingsEntry SETTINGS_ENTRIES[SETTINGS_COUNT] =
|
|||||||
{"previewBackgroundColorB=", "previewBackgroundColorB=%f", SETTINGS_TYPE_FLOAT, offsetof(Settings, previewBackgroundColorB)},
|
{"previewBackgroundColorB=", "previewBackgroundColorB=%f", SETTINGS_TYPE_FLOAT, offsetof(Settings, previewBackgroundColorB)},
|
||||||
{"previewBackgroundColorA=", "previewBackgroundColorA=%f", SETTINGS_TYPE_FLOAT, offsetof(Settings, previewBackgroundColorA)},
|
{"previewBackgroundColorA=", "previewBackgroundColorA=%f", SETTINGS_TYPE_FLOAT, offsetof(Settings, previewBackgroundColorA)},
|
||||||
{"editorIsGrid=", "editorIsGrid=%i", SETTINGS_TYPE_BOOL, offsetof(Settings, editorIsGrid)},
|
{"editorIsGrid=", "editorIsGrid=%i", SETTINGS_TYPE_BOOL, offsetof(Settings, editorIsGrid)},
|
||||||
|
{"editorIsGridSnap=", "editorIsGridSnap=%i", SETTINGS_TYPE_BOOL, offsetof(Settings, editorIsGridSnap)},
|
||||||
{"editorIsBorder=", "editorIsBorder=%i", SETTINGS_TYPE_BOOL, offsetof(Settings, editorIsBorder)},
|
{"editorIsBorder=", "editorIsBorder=%i", SETTINGS_TYPE_BOOL, offsetof(Settings, editorIsBorder)},
|
||||||
{"editorPanX=", "editorPanX=%f", SETTINGS_TYPE_FLOAT, offsetof(Settings, editorPanX)},
|
{"editorPanX=", "editorPanX=%f", SETTINGS_TYPE_FLOAT, offsetof(Settings, editorPanX)},
|
||||||
{"editorPanY=", "editorPanY=%f", SETTINGS_TYPE_FLOAT, offsetof(Settings, editorPanY)},
|
{"editorPanY=", "editorPanY=%f", SETTINGS_TYPE_FLOAT, offsetof(Settings, editorPanY)},
|
||||||
|
@@ -34,6 +34,7 @@ _tick(State* state)
|
|||||||
input_tick(&state->input);
|
input_tick(&state->input);
|
||||||
editor_tick(&state->editor);
|
editor_tick(&state->editor);
|
||||||
preview_tick(&state->preview);
|
preview_tick(&state->preview);
|
||||||
|
tool_tick(&state->tool);
|
||||||
dialog_tick(&state->dialog);
|
dialog_tick(&state->dialog);
|
||||||
imgui_tick(&state->imgui);
|
imgui_tick(&state->imgui);
|
||||||
}
|
}
|
||||||
@@ -104,10 +105,29 @@ init(State* state)
|
|||||||
printf(STRING_INFO_GLEW_INIT);
|
printf(STRING_INFO_GLEW_INIT);
|
||||||
|
|
||||||
resources_init(&state->resources);
|
resources_init(&state->resources);
|
||||||
dialog_init(&state->dialog, &state->anm2, &state->resources, state->window);
|
dialog_init(&state->dialog, &state->anm2, &state->reference, &state->resources, state->window);
|
||||||
|
tool_init(&state->tool, &state->input);
|
||||||
|
|
||||||
preview_init(&state->preview, &state->anm2, &state->resources, &state->input, &state->settings);
|
preview_init
|
||||||
editor_init(&state->editor, &state->resources, &state->settings);
|
(
|
||||||
|
&state->preview,
|
||||||
|
&state->anm2,
|
||||||
|
&state->reference,
|
||||||
|
&state->animationID,
|
||||||
|
&state->resources,
|
||||||
|
&state->settings
|
||||||
|
);
|
||||||
|
|
||||||
|
editor_init
|
||||||
|
(
|
||||||
|
&state->editor,
|
||||||
|
&state->anm2,
|
||||||
|
&state->reference,
|
||||||
|
&state->animationID,
|
||||||
|
&state->spritesheetID,
|
||||||
|
&state->resources,
|
||||||
|
&state->settings
|
||||||
|
);
|
||||||
|
|
||||||
imgui_init
|
imgui_init
|
||||||
(
|
(
|
||||||
@@ -116,9 +136,13 @@ init(State* state)
|
|||||||
&state->resources,
|
&state->resources,
|
||||||
&state->input,
|
&state->input,
|
||||||
&state->anm2,
|
&state->anm2,
|
||||||
|
&state->reference,
|
||||||
|
&state->animationID,
|
||||||
|
&state->spritesheetID,
|
||||||
&state->editor,
|
&state->editor,
|
||||||
&state->preview,
|
&state->preview,
|
||||||
&state->settings,
|
&state->settings,
|
||||||
|
&state->tool,
|
||||||
state->window,
|
state->window,
|
||||||
&state->glContext
|
&state->glContext
|
||||||
);
|
);
|
||||||
@@ -144,10 +168,11 @@ loop(State* state)
|
|||||||
SDL_Delay(TICK_DELAY - (state->tick - state->lastTick));
|
SDL_Delay(TICK_DELAY - (state->tick - state->lastTick));
|
||||||
|
|
||||||
_tick(state);
|
_tick(state);
|
||||||
_draw(state);
|
|
||||||
|
|
||||||
state->lastTick = state->tick;
|
state->lastTick = state->tick;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_draw(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
10
src/state.h
10
src/state.h
@@ -18,14 +18,18 @@ struct State
|
|||||||
Editor editor;
|
Editor editor;
|
||||||
Preview preview;
|
Preview preview;
|
||||||
Anm2 anm2;
|
Anm2 anm2;
|
||||||
|
Anm2Reference reference;
|
||||||
Resources resources;
|
Resources resources;
|
||||||
Settings settings;
|
Settings settings;
|
||||||
|
Tool tool;
|
||||||
|
bool isArgument = false;
|
||||||
|
bool isRunning = true;
|
||||||
char argument[PATH_MAX] = STRING_EMPTY;
|
char argument[PATH_MAX] = STRING_EMPTY;
|
||||||
char startPath[PATH_MAX] = STRING_EMPTY;
|
char startPath[PATH_MAX] = STRING_EMPTY;
|
||||||
bool isArgument = false;
|
s32 animationID = -1;
|
||||||
u64 tick = 0;
|
s32 spritesheetID = -1;
|
||||||
u64 lastTick = 0;
|
u64 lastTick = 0;
|
||||||
bool isRunning = true;
|
u64 tick = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
void init(State* state);
|
void init(State* state);
|
||||||
|
33
src/tool.cpp
Normal file
33
src/tool.cpp
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#include "tool.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
tool_init(Tool* self, Input* input)
|
||||||
|
{
|
||||||
|
self->input = input;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tool_tick(Tool* self)
|
||||||
|
{
|
||||||
|
if (!self->isEnabled) return;
|
||||||
|
|
||||||
|
/* Input handling */
|
||||||
|
if (key_press(&self->input->keyboard, INPUT_KEYS[INPUT_PAN]))
|
||||||
|
self->type = TOOL_PAN;
|
||||||
|
|
||||||
|
if (key_press(&self->input->keyboard, INPUT_KEYS[INPUT_MOVE]))
|
||||||
|
self->type = TOOL_MOVE;
|
||||||
|
|
||||||
|
if (key_press(&self->input->keyboard, INPUT_KEYS[INPUT_SCALE]))
|
||||||
|
self->type = TOOL_SCALE;
|
||||||
|
|
||||||
|
if (key_press(&self->input->keyboard, INPUT_KEYS[INPUT_CROP]))
|
||||||
|
self->type = TOOL_CROP;
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
key_press(&self->input->keyboard, INPUT_KEYS[INPUT_ROTATE_LEFT]) ||
|
||||||
|
key_press(&self->input->keyboard, INPUT_KEYS[INPUT_ROTATE_RIGHT])
|
||||||
|
)
|
||||||
|
self->type = TOOL_ROTATE;
|
||||||
|
}
|
23
src/tool.h
Normal file
23
src/tool.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
#define TOOL_COUNT (TOOL_CROP + 1)
|
||||||
|
enum ToolType
|
||||||
|
{
|
||||||
|
TOOL_PAN,
|
||||||
|
TOOL_MOVE,
|
||||||
|
TOOL_ROTATE,
|
||||||
|
TOOL_SCALE,
|
||||||
|
TOOL_CROP
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Tool
|
||||||
|
{
|
||||||
|
Input* input = NULL;
|
||||||
|
ToolType type = TOOL_PAN;
|
||||||
|
bool isEnabled = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
void tool_init(Tool* self, Input* input);
|
||||||
|
void tool_tick(Tool* self);
|
Reference in New Issue
Block a user