forming the skeleton
This commit is contained in:
12
src/COMMON.h
12
src/COMMON.h
@ -6,6 +6,7 @@
|
||||
#include <GL/gl.h>
|
||||
#include <glm/glm/glm.hpp>
|
||||
#include <glm/glm/gtc/type_ptr.hpp>
|
||||
#include <glm/glm/gtc/matrix_transform.hpp>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
@ -16,9 +17,10 @@
|
||||
#include <tinyxml2.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
#include <map>
|
||||
#include <ranges>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "STRINGS.h"
|
||||
|
||||
@ -48,6 +50,14 @@ static inline const char* enum_to_string(const char* arr[], s32 count, s32 index
|
||||
static inline s32 string_to_enum(const char* str, const char* const* arr, s32 n) { for (s32 i=0; i<n; ++i) if (!strcmp(str, arr[i])) return i; return -1; }
|
||||
static inline bool string_to_bool(const char* str) { if (strcmp(str, "true") == 0) return true; return false; }
|
||||
|
||||
static inline void working_directory_from_path_set(const char* path)
|
||||
{
|
||||
std::filesystem::path filePath = path;
|
||||
std::filesystem::path dir = filePath.parent_path();
|
||||
if (!dir.empty())
|
||||
std::filesystem::current_path(dir);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
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;
|
||||
|
@ -2,7 +2,8 @@
|
||||
|
||||
#include "COMMON.h"
|
||||
|
||||
struct PackedData
|
||||
/* TextureData */
|
||||
struct TextureData
|
||||
{
|
||||
const u8* data;
|
||||
u32 length;
|
||||
@ -266,25 +267,25 @@ static const unsigned char texture_arrow_down[] = {
|
||||
};
|
||||
static const unsigned int texture_arrow_down_len = 153;
|
||||
|
||||
#define PACKED_TEXTURE_COUNT (PACKED_TEXTURE_ARROW_DOWN + 1)
|
||||
enum PackedTextureType
|
||||
#define TEXTURE_COUNT (TEXTURE_ARROW_DOWN + 1)
|
||||
enum TextureType
|
||||
{
|
||||
PACKED_TEXTURE_EYE_OPEN,
|
||||
PACKED_TEXTURE_EYE_CLOSED,
|
||||
PACKED_TEXTURE_ANIMATION,
|
||||
PACKED_TEXTURE_EVENT,
|
||||
PACKED_TEXTURE_LAYER,
|
||||
PACKED_TEXTURE_NULL,
|
||||
PACKED_TEXTURE_ROOT,
|
||||
PACKED_TEXTURE_SPRITESHEET,
|
||||
PACKED_TEXTURE_TRIGGER,
|
||||
PACKED_TEXTURE_RECT_SHOW,
|
||||
PACKED_TEXTURE_RECT_HIDE,
|
||||
PACKED_TEXTURE_ARROW_UP,
|
||||
PACKED_TEXTURE_ARROW_DOWN
|
||||
TEXTURE_EYE_OPEN,
|
||||
TEXTURE_EYE_CLOSED,
|
||||
TEXTURE_ANIMATION,
|
||||
TEXTURE_EVENT,
|
||||
TEXTURE_LAYER,
|
||||
TEXTURE_NULL,
|
||||
TEXTURE_ROOT,
|
||||
TEXTURE_SPRITESHEET,
|
||||
TEXTURE_TRIGGER,
|
||||
TEXTURE_RECT_SHOW,
|
||||
TEXTURE_RECT_HIDE,
|
||||
TEXTURE_ARROW_UP,
|
||||
TEXTURE_ARROW_DOWN
|
||||
};
|
||||
|
||||
static const PackedData PACKED_TEXTURE_DATA[PACKED_TEXTURE_COUNT] =
|
||||
static const TextureData TEXTURE_DATA[TEXTURE_COUNT] =
|
||||
{
|
||||
{texture_eye_open, texture_eye_open_len},
|
||||
{texture_eye_closed, texture_eye_closed_len},
|
||||
@ -300,3 +301,45 @@ static const PackedData PACKED_TEXTURE_DATA[PACKED_TEXTURE_COUNT] =
|
||||
{texture_arrow_up, texture_arrow_up_len},
|
||||
{texture_arrow_down, texture_arrow_down_len},
|
||||
};
|
||||
|
||||
/* Shaders */
|
||||
struct ShaderData
|
||||
{
|
||||
const char* vertex;
|
||||
const char* fragment;
|
||||
};
|
||||
|
||||
#define SHADER_COUNT (SHADER + 1)
|
||||
enum ShaderType
|
||||
{
|
||||
SHADER
|
||||
};
|
||||
|
||||
static const char SHADER_VERTEX[] =
|
||||
"#version 330 core\n" \
|
||||
"layout (location = 0)\n" \
|
||||
"in vec2 i_position;\n" \
|
||||
"uniform mat4 u_transform;\n" \
|
||||
"\n" \
|
||||
"void main()\n" \
|
||||
"{\n" \
|
||||
" vec4 pos = vec4(i_position, 0.0, 1.0);\n" \
|
||||
" gl_Position = u_transform * pos;\n" \
|
||||
"}\n";
|
||||
|
||||
static const char SHADER_FRAGMENT[] = "#version 330 core\n" \
|
||||
"out vec4 FragColor;\n" \
|
||||
"uniform vec4 u_color;\n" \
|
||||
"\n" \
|
||||
"void main()\n" \
|
||||
"{\n" \
|
||||
" FragColor = u_color;\n" \
|
||||
"}\n";
|
||||
|
||||
static const char SHADER_UNIFORM_COLOR[] = "u_color";
|
||||
static const char SHADER_UNIFORM_TRANSFORM[] = "u_transform";
|
||||
|
||||
static const ShaderData SHADER_DATA[SHADER_COUNT] =
|
||||
{
|
||||
{SHADER_VERTEX, SHADER_FRAGMENT}
|
||||
};
|
122
src/STRINGS.h
122
src/STRINGS.h
@ -97,15 +97,20 @@
|
||||
#define STRING_IMGUI_FRAME_PROPERTIES_COLOR_OFFSET "Color Offset"
|
||||
|
||||
#define STRING_IMGUI_ANIMATION_PREVIEW "Animation Preview"
|
||||
#define STRING_IMGUI_ANIMATION_PREVIEW_LABEL "##Animation Preview"
|
||||
#define STRING_IMGUI_ANIMATION_PREVIEW_SETTINGS "##Animation Preview Settings"
|
||||
#define STRING_IMGUI_ANIMATION_PREVIEW_GRID_SETTINGS "##Grid Settings"
|
||||
#define STRING_IMGUI_ANIMATION_PREVIEW_GRID "Grid"
|
||||
#define STRING_IMGUI_ANIMATION_PREVIEW_GRID_SIZE "##Grid Size"
|
||||
#define STRING_IMGUI_ANIMATION_PREVIEW_GRID_COLOR "Color"
|
||||
#define STRING_IMGUI_ANIMATION_PREVIEW_ZOOM_SETTINGS "##Zoom Settings"
|
||||
#define STRING_IMGUI_ANIMATION_PREVIEW_VIEW_SETTINGS "##View Settings"
|
||||
#define STRING_IMGUI_ANIMATION_PREVIEW_ZOOM "Zoom"
|
||||
#define STRING_IMGUI_ANIMATION_PREVIEW_BACKGROUND_SETTINGS "##Background Settings"
|
||||
#define STRING_IMGUI_ANIMATION_PREVIEW_BACKGROUND_COLOR "Background Color"
|
||||
#define STRING_IMGUI_ANIMATION_PREVIEW_HELPER_SETTINGS "##Helper Settings"
|
||||
#define STRING_IMGUI_ANIMATION_PREVIEW_CENTER_VIEW "Center View"
|
||||
#define STRING_IMGUI_ANIMATION_PREVIEW_AXIS "Axes"
|
||||
#define STRING_IMGUI_ANIMATION_PREVIEW_AXIS_COLOR "Color"
|
||||
|
||||
#define STRING_IMGUI_SPRITESHEET_EDITOR "Spritesheet Editor"
|
||||
|
||||
@ -124,98 +129,75 @@
|
||||
#define STRING_IMGUI_TIMELINE_ANIMATIONS "Animations"
|
||||
#define STRING_IMGUI_TIMELINE_PLAY "|> Play"
|
||||
#define STRING_IMGUI_TIMELINE_PAUSE "|| Pause"
|
||||
#define STRING_IMGUI_TIMELINE_ADD_FRAME "+ Add Frame"
|
||||
#define STRING_IMGUI_TIMELINE_REMOVE_FRAME "- Remove Frame"
|
||||
#define STRING_IMGUI_TIMELINE_FRAME_ADD "Add Frame"
|
||||
#define STRING_IMGUI_TIMELINE_FRAME_REMOVE "Remove Frame"
|
||||
#define STRING_IMGUI_TIMELINE_FIT_ANIMATION_LENGTH "= Fit Animation Length"
|
||||
#define STRING_IMGUI_TIMELINE_ANIMATION LENGTH "Animation Length:"
|
||||
#define STRING_IMGUI_TIMELINE_VISIBLE "Visible"
|
||||
#define STRING_IMGUI_TIMELINE_LAYER "Layer"
|
||||
#define STRING_IMGUI_TIMELINE_NULL "Null"
|
||||
#define STRING_IMGUI_TIMELINE_RECT "Rect"
|
||||
#define STRING_IMGUI_TIMELINE_FRAME_INDICES "Frame Indices"
|
||||
#define STRING_IMGUI_TIMELINE_ANIMATION_LENGTH "Animation Length"
|
||||
#define STRING_IMGUI_TIMELINE_ELEMENT_TIMELINE "Element Timeline"
|
||||
#define STRING_IMGUI_TIMELINE_ELEMENTS "Elements"
|
||||
#define STRING_IMGUI_TIMELINE_ELEMENT_ADD "Add"
|
||||
#define STRING_IMGUI_TIMELINE_ELEMENT_ADD "Add Element"
|
||||
#define STRING_IMGUI_TIMELINE_ELEMENT_ADD_MENU "Element Add Menu"
|
||||
#define STRING_IMGUI_TIMELINE_ELEMENT_ADD_MENU_LAYER "Add Layer..."
|
||||
#define STRING_IMGUI_TIMELINE_ELEMENT_ADD_MENU_NULL "Add Null..."
|
||||
#define STRING_IMGUI_TIMELINE_ELEMENT_REMOVE "Remove"
|
||||
#define STRING_IMGUI_TIMELINE_ELEMENT_REMOVE "Remove Element"
|
||||
|
||||
#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_ADD "Add a new animation."
|
||||
#define STRING_IMGUI_TOOLTIP_ANIMATIONS_REMOVE "Removes 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_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_EVENTS_SELECT "Set the event for the trigger, or rename it."
|
||||
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_AXIS "Toggles the display of the X/Y axes."
|
||||
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_AXIS_COLOR "Changes the color of the X/Y axes."
|
||||
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_BACKGROUND_COLOR "Changes the background color of the animation preview."
|
||||
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_CENTER_VIEW "Centers the preview's pan."
|
||||
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_GRID "Toggles grid visibility on the animation preview."
|
||||
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_GRID_SIZE "Changes the grid's size, in pixels."
|
||||
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_GRID_COLOR "Changes the animation preview grid color."
|
||||
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_ZOOM "Changes the animation preview zoom level."
|
||||
#define STRING_IMGUI_TOOLTIP_EVENTS_ADD "Add a new event."
|
||||
#define STRING_IMGUI_TOOLTIP_EVENTS_REMOVE "Removes the selected event."
|
||||
#define STRING_IMGUI_TOOLTIP_SPRITESHEETS_ADD "Opens the file dialog to load in a new sprite."
|
||||
#define STRING_IMGUI_TOOLTIP_SPRITESHEETS_REMOVE "Removes the selected spritesheet."
|
||||
#define STRING_IMGUI_TOOLTIP_SPRITESHEETS_RELOAD "Reloads the selected spritesheet."
|
||||
#define STRING_IMGUI_TOOLTIP_SPRITESHEETS_REPLACE "Replaces the selected spritesheet; opens up the file dialog."
|
||||
#define STRING_IMGUI_TOOLTIP_PROPERTIES_FPS "Change the FPS of the animation."
|
||||
#define STRING_IMGUI_TOOLTIP_PROPERTIES_CREATED_BY "Change the author of the animation."
|
||||
#define STRING_IMGUI_TOOLTIP_PROPERTIES_CREATED_ON_NOW "Set the date of creation to the current system time."
|
||||
#define STRING_IMGUI_TOOLTIP_FRAME_PROPERTIES_POSITION "Change the position of the frame."
|
||||
#define STRING_IMGUI_TOOLTIP_EVENTS_SELECT "Set the event for the trigger, or rename it."
|
||||
#define STRING_IMGUI_TOOLTIP_FRAME_PROPERTIES_COLOR_OFFSET "Change the color offset of the frame."
|
||||
#define STRING_IMGUI_TOOLTIP_FRAME_PROPERTIES_CROP_POSITION "Change the crop position of the frame."
|
||||
#define STRING_IMGUI_TOOLTIP_FRAME_PROPERTIES_CROP_SIZE "Change the crop size of the frame."
|
||||
#define STRING_IMGUI_TOOLTIP_FRAME_PROPERTIES_PIVOT "Change the pivot of the frame."
|
||||
#define STRING_IMGUI_TOOLTIP_FRAME_PROPERTIES_SCALE "Change the scale of the frame."
|
||||
#define STRING_IMGUI_TOOLTIP_FRAME_PROPERTIES_ROTATION "Change the rotation of the frame."
|
||||
#define STRING_IMGUI_TOOLTIP_FRAME_PROPERTIES_DURATION "Change the duration of the frame."
|
||||
#define STRING_IMGUI_TOOLTIP_FRAME_PROPERTIES_TINT "Change the tint of the frame."
|
||||
#define STRING_IMGUI_TOOLTIP_FRAME_PROPERTIES_COLOR_OFFSET "Change the color offset of the frame."
|
||||
#define STRING_IMGUI_TOOLTIP_FRAME_PROPERTIES_VISIBLE "Toggles the visibility of the frame."
|
||||
#define STRING_IMGUI_TOOLTIP_FRAME_PROPERTIES_INTERPOLATED "Toggles the interpolation of the frame.\nBetween keyframes, will transform the values in the in-betweens to be smooth."
|
||||
#define STRING_IMGUI_TOOLTIP_FRAME_PROPERTIES_PIVOT "Change the pivot of the frame."
|
||||
#define STRING_IMGUI_TOOLTIP_FRAME_PROPERTIES_POSITION "Change the position of the frame."
|
||||
#define STRING_IMGUI_TOOLTIP_FRAME_PROPERTIES_ROTATION "Change the rotation of the frame."
|
||||
#define STRING_IMGUI_TOOLTIP_FRAME_PROPERTIES_SCALE "Change the scale of the frame."
|
||||
#define STRING_IMGUI_TOOLTIP_FRAME_PROPERTIES_TINT "Change the tint of the frame."
|
||||
#define STRING_IMGUI_TOOLTIP_FRAME_PROPERTIES_VISIBLE "Toggles the visibility of the frame."
|
||||
#define STRING_IMGUI_TOOLTIP_PROPERTIES_CREATED_BY "Change the author of the animation."
|
||||
#define STRING_IMGUI_TOOLTIP_PROPERTIES_CREATED_ON_NOW "Set the date of creation to the current system time."
|
||||
#define STRING_IMGUI_TOOLTIP_PROPERTIES_FPS "Change the FPS of the animation."
|
||||
#define STRING_IMGUI_TOOLTIP_SPRITESHEETS_ADD "Opens the file dialog to load in a new spritesheet."
|
||||
#define STRING_IMGUI_TOOLTIP_SPRITESHEETS_RELOAD "Reloads the selected spritesheet."
|
||||
#define STRING_IMGUI_TOOLTIP_SPRITESHEETS_REMOVE "Removes the selected spritesheet."
|
||||
#define STRING_IMGUI_TOOLTIP_SPRITESHEETS_REPLACE "Replaces the selected spritesheet; opens up the file dialog."
|
||||
#define STRING_IMGUI_TOOLTIP_SPRITESHEETS_SELECT "Select the spritesheet element."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_ANIMATION_LENGTH "Changes the current animation's length."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_ADD "Add a layer or null timeline element."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_NAME "Click to rename the element."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_SPRITESHEET "Click to change the spritesheet the layer is using."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_REMOVE "Remove a timeline element."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_SHIFT_UP "Shift this timeline element above.\nElements with higher indices will display further behind."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_SHIFT_DOWN "Shift this timeline element below.\nElements with lower indices will display further in front."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_VISIBLE "Toggle visibility for this element."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_RECT "Toggle visibility for a rectangle around the null."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_ROOT "This is the Root element."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_LAYER "This is a Layer element.\nThese are the main graphical animation elements.\nClick to rename."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_NAME "Click to rename the element."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_NULL "This is a Null element.\nThese are invisible elements where a game engine may have access to them for additional effects.\nClick to rename."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_RECT "Toggle visibility for a rectangle around the null."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_REMOVE "Remove a timeline element."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_ROOT "This is the Root element."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_SHIFT_DOWN "Shift this timeline element below.\nElements with lower indices will display further in front."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_SHIFT_UP "Shift this timeline element above.\nElements with higher indices will display further behind."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_SPRITESHEET "Click to change the spritesheet the layer is using."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_TRIGGERS "This is the animation's Triggers.\nTriggers are special activations; each is bound to an Event."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_PLAY "Plays the animation."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_VISIBLE "Toggle visibility for this element."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_FRAME_ADD "Add a frame to the current selected element."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_FRAME_REMOVE "Removes the selected frame from the current selected element."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_PAUSE "Pauses the animation."
|
||||
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_GRID "Toggles grid visibility on the animation preview."
|
||||
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_GRID_COLOR "Changes the animation preview grid color."
|
||||
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_GRID_SIZE "Changes the animation preview grid size (number of rows/columns)."
|
||||
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_ZOOM "Changes the animation preview zoom level."
|
||||
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_BACKGROUND_COLOR "Changes the background color of the animation preview."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_PLAY "Plays the animation."
|
||||
|
||||
#define STRING_OPENGL_VERSION "#version 330"
|
||||
|
||||
#define SHADER_VERTEX "#version 330 core\n" \
|
||||
"in vec2 l_position;\n" \
|
||||
"in vec2 l_uv;\n" \
|
||||
"\n" \
|
||||
"uniform mat3 u_view;\n" \
|
||||
"uniform mat3 u_projection;\n" \
|
||||
"uniform mat3 u_model;\n" \
|
||||
"\n" \
|
||||
"out vec2 o_uv;\n" \
|
||||
"\n" \
|
||||
"void main()\n" \
|
||||
"{\n" \
|
||||
" gl_Position = vec4(u_projection * u_view * u_model * vec3(l_position, 1.0), 1.0);\n" \
|
||||
" o_uv = l_uv;\n" \
|
||||
"}"
|
||||
|
||||
#define SHADER_FRAGMENT "#version 330 core\n" \
|
||||
"uniform vec4 u_tint;\n" \
|
||||
"uniform vec4 u_color_offset;\n" \
|
||||
"uniform sampler2D u_texture;\n" \
|
||||
"\n" \
|
||||
"in vec2 i_uv;\n" \
|
||||
"\n" \
|
||||
"out vec4 FragColor;\n" \
|
||||
"\n" \
|
||||
"void main()\n" \
|
||||
"{\n" \
|
||||
" FragColor = texture(u_texture, i_uv) * u_tint;\n" \
|
||||
" FragColor.rgb += u_color_offset.rgb;\n" \
|
||||
"\n" \
|
||||
" if (FragColor.a == 0.0) discard;\n" \
|
||||
"}\n"
|
||||
#define STRING_OPENGL_VERSION "#version 330"
|
25
src/anm2.cpp
25
src/anm2.cpp
@ -37,6 +37,7 @@ anm2_serialize(Anm2* self, const char* path)
|
||||
if (!self || !path)
|
||||
return false;
|
||||
|
||||
|
||||
/* Update creation date on first version */
|
||||
if (self->version == 0)
|
||||
anm2_created_on_set(self);
|
||||
@ -308,6 +309,8 @@ anm2_serialize(Anm2* self, const char* path)
|
||||
return false;
|
||||
}
|
||||
|
||||
working_directory_from_path_set(path);
|
||||
|
||||
printf(STRING_INFO_ANM2_WRITE, path);
|
||||
strncpy(self->path, path, PATH_MAX - 1);
|
||||
|
||||
@ -316,7 +319,7 @@ anm2_serialize(Anm2* self, const char* path)
|
||||
|
||||
/* Loads the .anm2 file and deserializes it into the struct equivalent */
|
||||
bool
|
||||
anm2_deserialize(Anm2* self, const char* path)
|
||||
anm2_deserialize(Anm2* self, Resources* resources, const char* path)
|
||||
{
|
||||
XMLDocument document;
|
||||
XMLError error;
|
||||
@ -349,6 +352,7 @@ anm2_deserialize(Anm2* self, const char* path)
|
||||
return false;
|
||||
}
|
||||
|
||||
resources_loaded_textures_free(resources);
|
||||
strncpy(self->path, path, PATH_MAX - 1);
|
||||
|
||||
root = document.FirstChildElement(ANM2_ELEMENT_STRINGS[ANM2_ELEMENT_ANIMATED_ACTOR]);
|
||||
@ -422,7 +426,6 @@ anm2_deserialize(Anm2* self, const char* path)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* Attributes */
|
||||
attribute = element->FirstAttribute();
|
||||
|
||||
@ -469,7 +472,8 @@ anm2_deserialize(Anm2* self, const char* path)
|
||||
}
|
||||
break;
|
||||
case ANM2_ATTRIBUTE_PATH:
|
||||
strncpy(lastSpritesheet->path, attribute->Value(), ANM2_STRING_MAX - 1);
|
||||
strncpy(lastSpritesheet->path, attribute->Value(), PATH_MAX - 1);
|
||||
anm2_spritesheet_texture_load(self, resources, attribute->Value(), id);
|
||||
break;
|
||||
case ANM2_ATTRIBUTE_NAME:
|
||||
switch (anm2Element)
|
||||
@ -638,6 +642,8 @@ anm2_deserialize(Anm2* self, const char* path)
|
||||
}
|
||||
}
|
||||
|
||||
working_directory_from_path_set(path);
|
||||
|
||||
printf(STRING_INFO_ANM2_READ, path);
|
||||
|
||||
return true;
|
||||
@ -719,4 +725,17 @@ anm2_new(Anm2* self)
|
||||
{
|
||||
*self = Anm2{};
|
||||
anm2_created_on_set(self);
|
||||
}
|
||||
|
||||
void
|
||||
anm2_spritesheet_texture_load(Anm2* self, Resources* resources, const char* path, s32 id)
|
||||
{
|
||||
Texture texture;
|
||||
|
||||
/* free texture if it exists */
|
||||
if (resources->loadedTextures.find(id) != resources->loadedTextures.end())
|
||||
texture_free(&resources->loadedTextures[id]);
|
||||
|
||||
texture_from_path_init(&texture, path);
|
||||
resources->loadedTextures[id] = texture;
|
||||
}
|
@ -1,12 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "COMMON.h"
|
||||
#include "resources.h"
|
||||
|
||||
#define ANM2_SCALE_CONVERT(x) ((f32)x / 100.0f)
|
||||
#define ANM2_TINT_CONVERT(x) ((f32)x / 255.0f)
|
||||
|
||||
#define ANM2_STRING_MAX 0xFF
|
||||
#define ANM2_STRING_FORMATTED_MAX 0xFFF
|
||||
#define ANM2_PATH_FORMATTED_MAX PATH_MAX + 0xFF
|
||||
#define ANM2_BUFFER_MAX 0xFFFFF
|
||||
#define ANM2_FPS_MIN 0
|
||||
#define ANM2_FPS_DEFAULT 30
|
||||
@ -117,7 +119,7 @@ enum Anm2AnimationType
|
||||
|
||||
struct Anm2Spritesheet
|
||||
{
|
||||
char path[ANM2_STRING_MAX] = STRING_EMPTY;
|
||||
char path[PATH_MAX] = STRING_EMPTY;
|
||||
};
|
||||
|
||||
struct Anm2Layer
|
||||
@ -213,8 +215,9 @@ void anm2_layer_remove(Anm2* self, s32 id);
|
||||
void anm2_null_add(Anm2* self);
|
||||
void anm2_null_remove(Anm2* self, s32 id);
|
||||
bool anm2_serialize(Anm2* self, const char* path);
|
||||
bool anm2_deserialize(Anm2* self, const char* path);
|
||||
bool anm2_deserialize(Anm2* self, Resources* resources, const char* path);
|
||||
void anm2_new(Anm2* self);
|
||||
void anm2_created_on_set(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);
|
@ -19,11 +19,18 @@ _dialog_callback(void* userdata, const char* const* filelist, s32 filter)
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
dialog_init(Dialog* self, Anm2* anm2, Resources* resources)
|
||||
{
|
||||
self->anm2 = anm2;
|
||||
self->resources = resources;
|
||||
}
|
||||
|
||||
/* Opens file dialog for user to pick anm2 files */
|
||||
void
|
||||
dialog_anm2_open(Dialog* self)
|
||||
{
|
||||
SDL_ShowOpenFileDialog(_dialog_callback, self, NULL, ANM2_DIALOG_FILE_FILTER, 1, NULL, false);
|
||||
SDL_ShowOpenFileDialog(_dialog_callback, self, NULL, DIALOG_FILE_FILTER_ANM2, 1, NULL, false);
|
||||
self->type = DIALOG_ANM2_OPEN;
|
||||
}
|
||||
|
||||
@ -31,22 +38,60 @@ dialog_anm2_open(Dialog* self)
|
||||
void
|
||||
dialog_anm2_save(Dialog* self)
|
||||
{
|
||||
SDL_ShowSaveFileDialog(_dialog_callback, self, NULL, ANM2_DIALOG_FILE_FILTER, 1, NULL);
|
||||
SDL_ShowSaveFileDialog(_dialog_callback, self, NULL, DIALOG_FILE_FILTER_ANM2, 1, NULL);
|
||||
self->type = DIALOG_ANM2_SAVE;
|
||||
}
|
||||
|
||||
/* Opens file dialog for user to pick png files for spritesheets */
|
||||
void
|
||||
dialog_png_open(Dialog* self)
|
||||
{
|
||||
SDL_ShowOpenFileDialog(_dialog_callback, self, NULL, DIALOG_FILE_FILTER_PNG, 1, NULL, false);
|
||||
self->type = DIALOG_PNG_OPEN;
|
||||
}
|
||||
|
||||
/* Opens file dialog for user to pick png file to replace selected one */
|
||||
void
|
||||
dialog_png_replace(Dialog* self)
|
||||
{
|
||||
SDL_ShowOpenFileDialog(_dialog_callback, self, NULL, DIALOG_FILE_FILTER_PNG, 1, NULL, false);
|
||||
self->type = DIALOG_PNG_REPLACE;
|
||||
}
|
||||
|
||||
void
|
||||
dialog_tick(Dialog* self)
|
||||
{
|
||||
if (self->isSelected)
|
||||
{
|
||||
Texture texture;
|
||||
s32 id;
|
||||
char relativePath[PATH_MAX];
|
||||
|
||||
/* Get the relative path */
|
||||
std::filesystem::path baseDirectory = std::filesystem::current_path();
|
||||
std::filesystem::path relativePathString = std::filesystem::relative(self->path, baseDirectory);
|
||||
|
||||
strncpy(relativePath, relativePathString.c_str(), PATH_MAX - 1);
|
||||
|
||||
switch (self->type)
|
||||
{
|
||||
case DIALOG_ANM2_OPEN:
|
||||
anm2_deserialize(self->anm2, self->path);
|
||||
anm2_deserialize(self->anm2, self->resources, relativePath);
|
||||
resources_loaded_textures_free(self->resources);
|
||||
break;
|
||||
case DIALOG_ANM2_SAVE:
|
||||
anm2_serialize(self->anm2, self->path);
|
||||
anm2_serialize(self->anm2, relativePath);
|
||||
break;
|
||||
case DIALOG_PNG_OPEN:
|
||||
id = map_next_id_get(self->resources->loadedTextures);
|
||||
self->anm2->spritesheets[id] = Anm2Spritesheet{};
|
||||
strncpy(self->anm2->spritesheets[id].path, relativePath, PATH_MAX);
|
||||
anm2_spritesheet_texture_load(self->anm2, self->resources, relativePath, id);
|
||||
break;
|
||||
case DIALOG_PNG_REPLACE:
|
||||
strncpy(self->anm2->spritesheets[self->replaceID].path, relativePath, PATH_MAX);
|
||||
anm2_spritesheet_texture_load(self->anm2, self->resources, relativePath, self->replaceID);
|
||||
self->replaceID = -1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
20
src/dialog.h
20
src/dialog.h
@ -1,26 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include "anm2.h"
|
||||
#include "resources.h"
|
||||
|
||||
static const SDL_DialogFileFilter ANM2_DIALOG_FILE_FILTER[] =
|
||||
static const SDL_DialogFileFilter DIALOG_FILE_FILTER_ANM2[] =
|
||||
{
|
||||
{"Anm2", "anm2;xml"}
|
||||
};
|
||||
|
||||
static const SDL_DialogFileFilter DIALOG_FILE_FILTER_PNG[] =
|
||||
{
|
||||
{"png", "png"}
|
||||
};
|
||||
|
||||
enum DialogType
|
||||
{
|
||||
DIALOG_NONE,
|
||||
DIALOG_ANM2_OPEN,
|
||||
DIALOG_ANM2_SAVE
|
||||
DIALOG_ANM2_SAVE,
|
||||
DIALOG_PNG_OPEN,
|
||||
DIALOG_PNG_REPLACE
|
||||
};
|
||||
|
||||
struct Dialog
|
||||
{
|
||||
Anm2* anm2 = NULL;
|
||||
enum DialogType type = DIALOG_ANM2_OPEN;
|
||||
Resources* resources = NULL;
|
||||
s32 replaceID = -1;
|
||||
enum DialogType type = DIALOG_NONE;
|
||||
char path[PATH_MAX] = "";
|
||||
bool isSelected = false;
|
||||
};
|
||||
|
||||
void dialog_init(Dialog* self, Anm2* anm2, Resources* resources);
|
||||
void dialog_anm2_open(Dialog* self);
|
||||
void dialog_png_open(Dialog* self);
|
||||
void dialog_png_replace(Dialog* self);
|
||||
void dialog_anm2_save(Dialog* self);
|
||||
void dialog_tick(Dialog* self);
|
387
src/imgui.cpp
387
src/imgui.cpp
@ -1,7 +1,19 @@
|
||||
#include "imgui.h"
|
||||
|
||||
static void _imgui_tooltip(const char* tooltip);
|
||||
static void _imgui_timeline_element(Imgui* self, void* element, s32* id, s32* index, Anm2AnimationType type, Anm2AnimationType* selectType, s32* selectID);
|
||||
|
||||
static void
|
||||
_imgui_timeline_element
|
||||
(
|
||||
Imgui* self,
|
||||
Anm2Animation* animation,
|
||||
void* element,
|
||||
s32* id,
|
||||
s32* index,
|
||||
Anm2AnimationType type,
|
||||
Anm2AnimationType* selectType,
|
||||
s32* selectID
|
||||
);
|
||||
|
||||
/* Makes a tooltip! */
|
||||
static void _imgui_tooltip(const char* tooltip)
|
||||
@ -12,17 +24,32 @@ static void _imgui_tooltip(const char* tooltip)
|
||||
|
||||
/* Displays each element of the timeline of a selected animation */
|
||||
static void
|
||||
_imgui_timeline_element(Imgui* self, void* element, s32* id, s32* index, Anm2AnimationType type, Anm2AnimationType* selectType, s32* selectID)
|
||||
_imgui_timeline_element
|
||||
(
|
||||
Imgui* self,
|
||||
Anm2Animation* animation,
|
||||
void* element,
|
||||
s32* id,
|
||||
s32* index,
|
||||
Anm2AnimationType type,
|
||||
Anm2AnimationType* selectType,
|
||||
s32* selectID
|
||||
)
|
||||
{
|
||||
static s32 selectedElementIndex = -1;
|
||||
static s32 selectedSpritesheetIndex = -1;
|
||||
void* frames = NULL;
|
||||
Anm2Layer* layer = NULL;
|
||||
Anm2LayerAnimation* layerAnimation = NULL;
|
||||
Anm2Null* null = NULL;
|
||||
Anm2NullAnimation* nullAnimation = NULL;
|
||||
Anm2RootAnimation* rootAnimation = NULL;
|
||||
Anm2Triggers* triggers = NULL;
|
||||
ImVec2 frameListSize = {IMGUI_TIMELINE_FRAME_SIZE.x * animation->frameNum, IMGUI_TIMELINE_ELEMENTS_TIMELINE_SIZE.y};
|
||||
ImTextureID iconTexture = -1;
|
||||
ImGuiWindowFlags windowFlags = 0 |
|
||||
ImGuiWindowFlags_NoScrollbar |
|
||||
ImGuiWindowFlags_NoScrollWithMouse;
|
||||
|
||||
bool isArrows = false;
|
||||
bool* isShowRect = NULL;
|
||||
@ -38,33 +65,37 @@ _imgui_timeline_element(Imgui* self, void* element, s32* id, s32* index, Anm2Ani
|
||||
{
|
||||
case ANM2_ROOT_ANIMATION:
|
||||
rootAnimation = (Anm2RootAnimation*)element;
|
||||
iconTexture = self->packed->textures[PACKED_TEXTURE_ROOT].handle;
|
||||
iconTexture = self->resources->textures[TEXTURE_ROOT].handle;
|
||||
strncpy(nameVisible, STRING_IMGUI_TIMELINE_ROOT, ANM2_STRING_FORMATTED_MAX);
|
||||
isVisible = &rootAnimation->isVisible;
|
||||
frames = &rootAnimation->frames;
|
||||
break;
|
||||
case ANM2_LAYER_ANIMATION:
|
||||
layerAnimation = (Anm2LayerAnimation*)element;
|
||||
layer = &self->anm2->layers[*id];
|
||||
iconTexture = self->packed->textures[PACKED_TEXTURE_LAYER].handle;
|
||||
iconTexture = self->resources->textures[TEXTURE_LAYER].handle;
|
||||
isVisible = &layerAnimation->isVisible;
|
||||
spritesheetID = &layer->spritesheetID;
|
||||
namePointer = layer->name;
|
||||
frames = &layerAnimation->frames;
|
||||
snprintf(nameBuffer, ANM2_STRING_MAX, "%s", namePointer);
|
||||
snprintf(nameVisible, ANM2_STRING_FORMATTED_MAX, STRING_IMGUI_TIMELINE_ELEMENT_FORMAT, *id, namePointer);
|
||||
break;
|
||||
case ANM2_NULL_ANIMATION:
|
||||
nullAnimation = (Anm2NullAnimation*)element;
|
||||
null = &self->anm2->nulls[*id];
|
||||
iconTexture = self->packed->textures[PACKED_TEXTURE_NULL].handle;
|
||||
iconTexture = self->resources->textures[TEXTURE_NULL].handle;
|
||||
isVisible = &nullAnimation->isVisible;
|
||||
isShowRect = &null->isShowRect;
|
||||
namePointer = null->name;
|
||||
frames = &nullAnimation->frames;
|
||||
snprintf(nameBuffer, ANM2_STRING_MAX, "%s", namePointer);
|
||||
snprintf(nameVisible, ANM2_STRING_FORMATTED_MAX, STRING_IMGUI_TIMELINE_ELEMENT_FORMAT, *id, namePointer);
|
||||
break;
|
||||
case ANM2_TRIGGERS:
|
||||
triggers = (Anm2Triggers*)element;
|
||||
iconTexture = self->packed->textures[PACKED_TEXTURE_TRIGGER].handle;
|
||||
frames = &triggers->items;
|
||||
iconTexture = self->resources->textures[TEXTURE_TRIGGER].handle;
|
||||
strncpy(nameVisible, STRING_IMGUI_TIMELINE_TRIGGERS, ANM2_STRING_FORMATTED_MAX);
|
||||
isVisible = &triggers->isVisible;
|
||||
break;
|
||||
@ -72,7 +103,7 @@ _imgui_timeline_element(Imgui* self, void* element, s32* id, s32* index, Anm2Ani
|
||||
break;
|
||||
}
|
||||
|
||||
ImGui::BeginChild(nameVisible, IMGUI_TIMELINE_ELEMENT_SIZE, true, ImGuiWindowFlags_NoScrollbar);
|
||||
ImGui::BeginChild(nameVisible, IMGUI_TIMELINE_ELEMENT_SIZE, true, windowFlags);
|
||||
|
||||
ImGui::PushID(*index);
|
||||
|
||||
@ -95,7 +126,7 @@ _imgui_timeline_element(Imgui* self, void* element, s32* id, s32* index, Anm2Ani
|
||||
if (canMoveUp)
|
||||
{
|
||||
auto target = isReversed ? std::next(it) : std::prev(it);
|
||||
if (target != map.end() && ImGui::ImageButton(STRING_IMGUI_TIMELINE_ELEMENT_SHIFT_ABOVE, self->packed->textures[PACKED_TEXTURE_ARROW_UP].handle, IMGUI_ICON_SIZE))
|
||||
if (target != map.end() && ImGui::ImageButton(STRING_IMGUI_TIMELINE_ELEMENT_SHIFT_ABOVE, self->resources->textures[TEXTURE_ARROW_UP].handle, IMGUI_ICON_SIZE))
|
||||
{
|
||||
map_swap(map, it->first, target->first);
|
||||
*didSwap = true;
|
||||
@ -107,11 +138,14 @@ _imgui_timeline_element(Imgui* self, void* element, s32* id, s32* index, Anm2Ani
|
||||
|
||||
if (canMoveDown)
|
||||
{
|
||||
|
||||
if (!canMoveUp)
|
||||
ImGui::Dummy(IMGUI_ICON_BUTTON_SIZE);
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
auto target = isReversed ? std::prev(it) : std::next(it);
|
||||
if (target != map.end() && ImGui::ImageButton(STRING_IMGUI_TIMELINE_ELEMENT_SHIFT_BELOW, self->packed->textures[PACKED_TEXTURE_ARROW_DOWN].handle, IMGUI_ICON_SIZE))
|
||||
if (target != map.end() && ImGui::ImageButton(STRING_IMGUI_TIMELINE_ELEMENT_SHIFT_BELOW, self->resources->textures[TEXTURE_ARROW_DOWN].handle, IMGUI_ICON_SIZE))
|
||||
{
|
||||
map_swap(map, it->first, target->first);
|
||||
*didSwap = true;
|
||||
@ -176,7 +210,7 @@ _imgui_timeline_element(Imgui* self, void* element, s32* id, s32* index, Anm2Ani
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ANM2_ROOT_ANIMATION:
|
||||
@ -200,18 +234,22 @@ _imgui_timeline_element(Imgui* self, void* element, s32* id, s32* index, Anm2Ani
|
||||
/* Visiblity */
|
||||
if (isVisible)
|
||||
{
|
||||
ImVec2 cursorPos;
|
||||
ImTextureID visibilityIcon = *isVisible
|
||||
? self->packed->textures[PACKED_TEXTURE_EYE_OPEN].handle
|
||||
: self->packed->textures[PACKED_TEXTURE_EYE_CLOSED].handle;
|
||||
? self->resources->textures[TEXTURE_EYE_OPEN].handle
|
||||
: self->resources->textures[TEXTURE_EYE_CLOSED].handle;
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - IMGUI_ICON_BUTTON_SIZE.x - ImGui::GetStyle().FramePadding.x * 2);
|
||||
|
||||
cursorPos = ImGui::GetCursorPos();
|
||||
ImGui::SetCursorPosX(cursorPos.x + ImGui::GetContentRegionAvail().x - IMGUI_ICON_BUTTON_SIZE.x - ImGui::GetStyle().FramePadding.x * 2);
|
||||
|
||||
if (ImGui::ImageButton(STRING_IMGUI_TIMELINE_VISIBLE, visibilityIcon, IMGUI_ICON_SIZE))
|
||||
*isVisible = !*isVisible;
|
||||
|
||||
_imgui_tooltip(STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_VISIBLE);
|
||||
|
||||
ImGui::SetCursorPos(cursorPos);
|
||||
}
|
||||
|
||||
/* Spritesheet IDs */
|
||||
@ -224,14 +262,14 @@ _imgui_timeline_element(Imgui* self, void* element, s32* id, s32* index, Anm2Ani
|
||||
else
|
||||
snprintf(spritesheetIDName, ANM2_STRING_FORMATTED_MAX, STRING_IMGUI_TIMELINE_SPRITESHEET_FORMAT, *spritesheetID);
|
||||
|
||||
ImGui::Image(self->packed->textures[PACKED_TEXTURE_SPRITESHEET].handle, IMGUI_ICON_SIZE);
|
||||
ImGui::Image(self->resources->textures[TEXTURE_SPRITESHEET].handle, IMGUI_ICON_SIZE);
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::BeginChild(STRING_IMGUI_TIMELINE_ELEMENT_SPRITESHEET_ID_LABEL, IMGUI_TIMELINE_SPRITESHEET_ID_SIZE);
|
||||
|
||||
if (selectedSpritesheetIndex == *index)
|
||||
{
|
||||
if (ImGui::DragInt(STRING_IMGUI_TIMELINE_ELEMENT_SPRITESHEET_ID_LABEL, spritesheetID, 0, 1, self->anm2->spritesheets.size() - 1))
|
||||
if (ImGui::InputInt(STRING_IMGUI_TIMELINE_ELEMENT_SPRITESHEET_ID_LABEL, spritesheetID, 0, 0, ImGuiInputTextFlags_None))
|
||||
selectedSpritesheetIndex = -1;
|
||||
}
|
||||
else
|
||||
@ -249,10 +287,10 @@ _imgui_timeline_element(Imgui* self, void* element, s32* id, s32* index, Anm2Ani
|
||||
if (isShowRect)
|
||||
{
|
||||
ImTextureID rectIcon = *isShowRect
|
||||
? self->packed->textures[PACKED_TEXTURE_RECT_HIDE].handle
|
||||
: self->packed->textures[PACKED_TEXTURE_RECT_SHOW].handle;
|
||||
? self->resources->textures[TEXTURE_RECT_HIDE].handle
|
||||
: self->resources->textures[TEXTURE_RECT_SHOW].handle;
|
||||
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - IMGUI_ICON_BUTTON_SIZE.x - ImGui::GetStyle().FramePadding.x * 2);
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - ((IMGUI_ICON_BUTTON_SIZE.x - ImGui::GetStyle().FramePadding.x * 2) * 4));
|
||||
|
||||
if (ImGui::ImageButton(STRING_IMGUI_TIMELINE_RECT, rectIcon, IMGUI_ICON_SIZE))
|
||||
*isShowRect = !*isShowRect;
|
||||
@ -265,25 +303,69 @@ _imgui_timeline_element(Imgui* self, void* element, s32* id, s32* index, Anm2Ani
|
||||
selectedElementIndex = -1;
|
||||
selectedSpritesheetIndex = -1;
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
|
||||
ImGui::EndGroup();
|
||||
|
||||
ImGui::PopID();
|
||||
|
||||
ImGui::EndChild();
|
||||
|
||||
if (animation->frameNum > 0)
|
||||
{
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::PushID(*index);
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
|
||||
ImGui::BeginChild(STRING_IMGUI_TIMELINE_ELEMENT_TIMELINE, frameListSize, true);
|
||||
|
||||
for (s32 i = 0; i < animation->frameNum; i++)
|
||||
{
|
||||
ImGui::PushID(i);
|
||||
if (ImGui::Button(" ", IMGUI_TIMELINE_FRAME_SIZE))
|
||||
{
|
||||
|
||||
}
|
||||
ImGui::SameLine(0.0f, 0.0f);
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
*index = *index + 1;
|
||||
}
|
||||
|
||||
void
|
||||
imgui_init(SDL_Window* window, SDL_GLContext glContext)
|
||||
imgui_init
|
||||
(
|
||||
Imgui* self,
|
||||
Dialog* dialog,
|
||||
Resources* resources,
|
||||
Input* input,
|
||||
Anm2* anm2,
|
||||
Preview* preview,
|
||||
SDL_Window* window,
|
||||
SDL_GLContext* glContext
|
||||
)
|
||||
{
|
||||
IMGUI_CHECKVERSION();
|
||||
|
||||
self->dialog = dialog;
|
||||
self->resources = resources;
|
||||
self->input = input;
|
||||
self->anm2 = anm2;
|
||||
self->preview = preview;
|
||||
self->window = window;
|
||||
self->glContext = glContext;
|
||||
|
||||
ImGui::CreateContext();
|
||||
ImGui::StyleColorsDark();
|
||||
|
||||
ImGui_ImplSDL3_InitForOpenGL(window, glContext);
|
||||
ImGui_ImplSDL3_InitForOpenGL(self->window, *self->glContext);
|
||||
ImGui_ImplOpenGL3_Init(STRING_OPENGL_VERSION);
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
@ -302,6 +384,10 @@ imgui_tick(Imgui* self)
|
||||
static Anm2AnimationType selectedTimelineElementType = ANM2_NONE;
|
||||
static bool isInterpolated = true;
|
||||
static bool isVisible = true;
|
||||
static bool isHoverPreview = false;
|
||||
static ImRect previewWindowRect;
|
||||
static ImVec2 settingsCursorPos;
|
||||
static bool isFirstTick = true;
|
||||
|
||||
static f32 rotation = 0;
|
||||
static s32 duration = 0;
|
||||
@ -313,27 +399,15 @@ imgui_tick(Imgui* self)
|
||||
static vec3 offset = {0.0f, 0.0f, 0.0f};
|
||||
static vec4 tint = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
|
||||
ImVec2 previewWindowSize;
|
||||
ImVec2 previewSize;
|
||||
f32 previewAspect = 0.0f;
|
||||
f32 previewWindowAspect = 0.0f;
|
||||
|
||||
ImGuiWindowFlags taskbarWindowFlags;
|
||||
ImGuiWindowFlags dockspaceWindowFlags;
|
||||
ImGuiDockNodeFlags dockNodeFlags;
|
||||
|
||||
ImGui_ImplSDL3_NewFrame();
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
taskbarWindowFlags = 0 |
|
||||
ImGuiWindowFlags taskbarWindowFlags = 0 |
|
||||
ImGuiWindowFlags_NoTitleBar |
|
||||
ImGuiWindowFlags_NoResize |
|
||||
ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_NoScrollbar |
|
||||
ImGuiWindowFlags_NoScrollWithMouse |
|
||||
ImGuiWindowFlags_NoSavedSettings;
|
||||
|
||||
dockspaceWindowFlags = 0 |
|
||||
ImGuiWindowFlags dockspaceWindowFlags = 0 |
|
||||
ImGuiWindowFlags_NoTitleBar |
|
||||
ImGuiWindowFlags_NoCollapse |
|
||||
ImGuiWindowFlags_NoResize |
|
||||
@ -341,9 +415,23 @@ imgui_tick(Imgui* self)
|
||||
ImGuiWindowFlags_NoBringToFrontOnFocus |
|
||||
ImGuiWindowFlags_NoNavFocus;
|
||||
|
||||
dockNodeFlags = 0 |
|
||||
ImGuiWindowFlags childWindowFlags = 0 |
|
||||
ImGuiWindowFlags_NoTitleBar |
|
||||
ImGuiWindowFlags_NoCollapse |
|
||||
ImGuiWindowFlags_NoResize |
|
||||
ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_NoBringToFrontOnFocus |
|
||||
ImGuiWindowFlags_NoNavFocus |
|
||||
ImGuiWindowFlags_NoScrollbar |
|
||||
ImGuiWindowFlags_NoScrollWithMouse;
|
||||
|
||||
ImGuiDockNodeFlags dockNodeFlags = 0 |
|
||||
ImGuiDockNodeFlags_PassthruCentralNode;
|
||||
|
||||
|
||||
ImGui_ImplSDL3_NewFrame();
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
|
||||
/* Taskbar */
|
||||
@ -457,7 +545,7 @@ imgui_tick(Imgui* self)
|
||||
|
||||
ImGui::PushID(id);
|
||||
|
||||
ImGui::Image(self->packed->textures[PACKED_TEXTURE_ANIMATION].handle, IMGUI_ICON_SIZE);
|
||||
ImGui::Image(self->resources->textures[TEXTURE_ANIMATION].handle, IMGUI_ICON_SIZE);
|
||||
ImGui::SameLine();
|
||||
|
||||
if (isSelected)
|
||||
@ -545,7 +633,7 @@ imgui_tick(Imgui* self)
|
||||
|
||||
ImGui::PushID(id);
|
||||
|
||||
ImGui::Image(self->packed->textures[PACKED_TEXTURE_EVENT].handle, IMGUI_ICON_SIZE);
|
||||
ImGui::Image(self->resources->textures[TEXTURE_EVENT].handle, IMGUI_ICON_SIZE);
|
||||
ImGui::SameLine();
|
||||
|
||||
isSelected = selectedEventID == id;
|
||||
@ -596,46 +684,70 @@ imgui_tick(Imgui* self)
|
||||
|
||||
for (auto [id, spritesheet] : self->anm2->spritesheets)
|
||||
{
|
||||
ImVec2 spritesheetPreviewSize = IMGUI_SPRITESHEET_PREVIEW_SIZE;
|
||||
char spritesheetString[ANM2_STRING_FORMATTED_MAX];
|
||||
bool isSelected = false;
|
||||
|
||||
snprintf(spritesheetString, ANM2_STRING_FORMATTED_MAX, STRING_IMGUI_SPRITESHEET_FORMAT, (s32)id, spritesheet.path);
|
||||
f32 spritesheetAspect = (f32)self->resources->loadedTextures[id].size.x / self->resources->loadedTextures[id].size.y;
|
||||
|
||||
if ((IMGUI_SPRITESHEET_PREVIEW_SIZE.x / IMGUI_SPRITESHEET_PREVIEW_SIZE.y) > spritesheetAspect)
|
||||
spritesheetPreviewSize.x = IMGUI_SPRITESHEET_PREVIEW_SIZE.y * spritesheetAspect;
|
||||
else
|
||||
spritesheetPreviewSize.y = IMGUI_SPRITESHEET_PREVIEW_SIZE.x / spritesheetAspect;
|
||||
|
||||
snprintf(spritesheetString, ANM2_PATH_FORMATTED_MAX, STRING_IMGUI_SPRITESHEET_FORMAT, (s32)id, spritesheet.path);
|
||||
|
||||
ImGui::BeginChild(spritesheetString, IMGUI_SPRITESHEET_SIZE, true, ImGuiWindowFlags_None);
|
||||
|
||||
ImGui::PushID(id);
|
||||
|
||||
ImGui::Image(self->packed->textures[PACKED_TEXTURE_SPRITESHEET].handle, IMGUI_ICON_SIZE);
|
||||
ImGui::Image(self->resources->textures[TEXTURE_SPRITESHEET].handle, IMGUI_ICON_SIZE);
|
||||
ImGui::SameLine();
|
||||
|
||||
isSelected = selectedSpritesheetID == id;
|
||||
if (ImGui::Selectable(spritesheetString, isSelected))
|
||||
selectedSpritesheetID = id;
|
||||
|
||||
_imgui_tooltip(STRING_IMGUI_TOOLTIP_SPRITESHEETS_SELECT);
|
||||
|
||||
ImGui::Image(self->resources->loadedTextures[id].handle, spritesheetPreviewSize);
|
||||
|
||||
ImGui::PopID();
|
||||
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
ImGui::Button(STRING_IMGUI_SPRITESHEETS_ADD);
|
||||
if (ImGui::Button(STRING_IMGUI_SPRITESHEETS_ADD))
|
||||
dialog_png_open(self->dialog);
|
||||
_imgui_tooltip(STRING_IMGUI_TOOLTIP_SPRITESHEETS_ADD);
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (selectedSpritesheetID != -1)
|
||||
{
|
||||
/* Remove */
|
||||
if (ImGui::Button(STRING_IMGUI_SPRITESHEETS_REMOVE))
|
||||
{
|
||||
self->resources->loadedTextures.erase(selectedSpritesheetID);
|
||||
self->anm2->spritesheets.erase(selectedSpritesheetID);
|
||||
selectedSpritesheetID = -1;
|
||||
}
|
||||
_imgui_tooltip(STRING_IMGUI_TOOLTIP_SPRITESHEETS_REMOVE);
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::Button(STRING_IMGUI_SPRITESHEETS_RELOAD);
|
||||
|
||||
/* Reload */
|
||||
if (ImGui::Button(STRING_IMGUI_SPRITESHEETS_RELOAD))
|
||||
anm2_spritesheet_texture_load(self->anm2, self->resources, self->anm2->spritesheets[selectedSpritesheetID].path, selectedSpritesheetID);
|
||||
_imgui_tooltip(STRING_IMGUI_TOOLTIP_SPRITESHEETS_RELOAD);
|
||||
ImGui::SameLine();
|
||||
ImGui::Button(STRING_IMGUI_SPRITESHEETS_REPLACE);
|
||||
|
||||
/* Replace */
|
||||
if (ImGui::Button(STRING_IMGUI_SPRITESHEETS_REPLACE))
|
||||
{
|
||||
self->dialog->replaceID = selectedSpritesheetID;
|
||||
dialog_png_replace(self->dialog);
|
||||
}
|
||||
_imgui_tooltip(STRING_IMGUI_TOOLTIP_SPRITESHEETS_REPLACE);
|
||||
}
|
||||
|
||||
@ -686,14 +798,58 @@ imgui_tick(Imgui* self)
|
||||
ImGui::End();
|
||||
|
||||
/* -- Animation Preview -- */
|
||||
|
||||
ImGui::Begin(STRING_IMGUI_ANIMATION_PREVIEW);
|
||||
|
||||
/* elements drawn out of order in order to get the size of the preview before how it visually appears */
|
||||
settingsCursorPos = ImGui::GetCursorPos();
|
||||
ImGui::SetCursorPos(IMGUI_ANIMATION_PREVIEW_POSITION);
|
||||
|
||||
ImGui::BeginChild(STRING_IMGUI_ANIMATION_PREVIEW_LABEL, ImVec2(0, 0), true, childWindowFlags);
|
||||
|
||||
previewWindowRect = ImGui::GetCurrentWindow()->ClipRect;
|
||||
|
||||
ImGui::Image(self->preview->texture, ImVec2(PREVIEW_SIZE.x, PREVIEW_SIZE.y));
|
||||
|
||||
/* Panning */
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
SDL_SetCursor(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_MOVE));
|
||||
isHoverPreview = true;
|
||||
|
||||
if (mouse_held(&self->input->mouse, MOUSE_LEFT))
|
||||
{
|
||||
self->preview->pan.x += self->input->mouse.delta.x;
|
||||
self->preview->pan.y -= self->input->mouse.delta.y;
|
||||
}
|
||||
|
||||
self->preview->zoom = self->preview->zoom == PREVIEW_ZOOM_MIN ? 0 : self->preview->zoom;
|
||||
|
||||
if (self->input->mouse.wheelDeltaY > 0)
|
||||
self->preview->zoom += PREVIEW_ZOOM_STEP;
|
||||
|
||||
if (self->input->mouse.wheelDeltaY < 0)
|
||||
self->preview->zoom -= PREVIEW_ZOOM_STEP;
|
||||
|
||||
self->preview->zoom = CLAMP(self->preview->zoom, PREVIEW_ZOOM_MIN, PREVIEW_ZOOM_MAX);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isHoverPreview)
|
||||
{
|
||||
SDL_SetCursor(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_DEFAULT));
|
||||
isHoverPreview = false;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::SetCursorPos(settingsCursorPos);
|
||||
|
||||
/* Settings */
|
||||
ImGui::BeginChild(STRING_IMGUI_ANIMATION_PREVIEW_SETTINGS, IMGUI_ANIMATION_PREVIEW_SETTINGS_SIZE, true);
|
||||
ImGui::BeginChild(STRING_IMGUI_ANIMATION_PREVIEW_SETTINGS, IMGUI_ANIMATION_PREVIEW_SETTINGS_SIZE, true, childWindowFlags);
|
||||
|
||||
/* Grid settings */
|
||||
ImGui::BeginChild(STRING_IMGUI_ANIMATION_PREVIEW_GRID_SETTINGS, IMGUI_ANIMATION_PREVIEW_SETTINGS_GRID_SIZE, true);
|
||||
ImGui::BeginChild(STRING_IMGUI_ANIMATION_PREVIEW_GRID_SETTINGS, IMGUI_ANIMATION_PREVIEW_SETTINGS_CHILD_SIZE, true);
|
||||
|
||||
/* Grid toggle */
|
||||
ImGui::Checkbox(STRING_IMGUI_ANIMATION_PREVIEW_GRID, &self->preview->isGrid);
|
||||
@ -715,32 +871,60 @@ imgui_tick(Imgui* self)
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
/* Zoom settings */
|
||||
ImGui::BeginChild(STRING_IMGUI_ANIMATION_PREVIEW_ZOOM_SETTINGS, IMGUI_ANIMATION_PREVIEW_SETTINGS_ZOOM_SIZE, true);
|
||||
/* Helper settings */
|
||||
ImGui::BeginChild(STRING_IMGUI_ANIMATION_PREVIEW_HELPER_SETTINGS, IMGUI_ANIMATION_PREVIEW_SETTINGS_CHILD_SIZE, true);
|
||||
|
||||
/* Axis toggle */
|
||||
ImGui::Checkbox(STRING_IMGUI_ANIMATION_PREVIEW_AXIS, &self->preview->isAxis);
|
||||
_imgui_tooltip(STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_AXIS);
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
/* Axis colors*/
|
||||
ImGui::ColorEdit4(STRING_IMGUI_ANIMATION_PREVIEW_AXIS_COLOR, value_ptr(self->preview->axisColor), ImGuiColorEditFlags_NoInputs);
|
||||
_imgui_tooltip(STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_AXIS_COLOR);
|
||||
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
/* View settings */
|
||||
ImGui::BeginChild(STRING_IMGUI_ANIMATION_PREVIEW_VIEW_SETTINGS, IMGUI_ANIMATION_PREVIEW_SETTINGS_CHILD_SIZE, true);
|
||||
|
||||
/* Zoom */
|
||||
ImGui::DragFloat(STRING_IMGUI_ANIMATION_PREVIEW_ZOOM, &self->preview->zoom, 1, PREVIEW_ZOOM_MIN, PREVIEW_ZOOM_MAX, "%.0f");
|
||||
_imgui_tooltip(STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_ZOOM);
|
||||
|
||||
/* Center view */
|
||||
if (ImGui::Button(STRING_IMGUI_ANIMATION_PREVIEW_CENTER_VIEW) || isFirstTick)
|
||||
{
|
||||
ImVec2 previewWindowSize = previewWindowRect.GetSize();
|
||||
|
||||
previewWindowSize.x = MAX(previewWindowSize.x, PREVIEW_SIZE.x);
|
||||
previewWindowSize.y = MAX(previewWindowSize.y, PREVIEW_SIZE.y);
|
||||
|
||||
/* Based on the preview's crop in its window, adjust the preview */
|
||||
self->preview->pan.x = PREVIEW_CENTER.x + ((previewWindowSize.x - PREVIEW_SIZE.x) / 2);
|
||||
self->preview->pan.y = PREVIEW_CENTER.y - ((previewWindowSize.y - PREVIEW_SIZE.y) / 2);
|
||||
|
||||
}
|
||||
_imgui_tooltip(STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_CENTER_VIEW);
|
||||
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
/* Background settings */
|
||||
ImGui::BeginChild(STRING_IMGUI_ANIMATION_PREVIEW_BACKGROUND_SETTINGS, IMGUI_ANIMATION_PREVIEW_SETTINGS_BACKGROUND_SIZE, true);
|
||||
ImGui::BeginChild(STRING_IMGUI_ANIMATION_PREVIEW_BACKGROUND_SETTINGS, IMGUI_ANIMATION_PREVIEW_SETTINGS_CHILD_SIZE, true);
|
||||
|
||||
/* Background color */
|
||||
ImGui::ColorEdit4(STRING_IMGUI_ANIMATION_PREVIEW_BACKGROUND_COLOR, value_ptr(self->preview->color), ImGuiColorEditFlags_NoInputs);
|
||||
ImGui::ColorEdit4(STRING_IMGUI_ANIMATION_PREVIEW_BACKGROUND_COLOR, value_ptr(self->preview->backgroundColor), ImGuiColorEditFlags_NoInputs);
|
||||
_imgui_tooltip(STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_BACKGROUND_COLOR);
|
||||
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::Image(self->preview->texture, ImVec2(PREVIEW_SIZE.x, PREVIEW_SIZE.y));
|
||||
|
||||
ImGui::End();
|
||||
|
||||
/* -- Spritesheet Editor -- */
|
||||
@ -755,12 +939,31 @@ imgui_tick(Imgui* self)
|
||||
if (selectedAnimationID != -1)
|
||||
{
|
||||
s32 index = 0;
|
||||
ImVec2 timelineSize = IMGUI_TIMELINE_SIZE;
|
||||
Anm2Animation* animation = &self->anm2->animations[selectedAnimationID];
|
||||
|
||||
ImGui::BeginChild(STRING_IMGUI_TIMELINE_ANIMATIONS, IMGUI_TIMELINE_ELEMENT_LIST_SIZE, true);
|
||||
ImVec2 frameIndicesSize =
|
||||
{IMGUI_TIMELINE_FRAME_SIZE.x * animation->frameNum, IMGUI_TIMELINE_FRAME_INDICES_SIZE.y};
|
||||
|
||||
timelineSize.y = ImGui::GetContentRegionAvail().y - IMGUI_TIMELINE_OFFSET_Y;
|
||||
|
||||
ImGui::BeginChild(STRING_IMGUI_TIMELINE_ANIMATIONS, timelineSize, true);
|
||||
|
||||
/* Element top bar */
|
||||
ImGui::BeginChild(STRING_IMGUI_TIMELINE_ELEMENTS, IMGUI_TIMELINE_ELEMENTS_BAR_SIZE, true);
|
||||
ImGui::Text(STRING_IMGUI_TIMELINE_ELEMENTS);
|
||||
ImGui::EndChild();
|
||||
|
||||
|
||||
/* Frame indicies */
|
||||
if (animation->frameNum > 0)
|
||||
{
|
||||
ImGui::SameLine();
|
||||
ImGui::BeginChild(STRING_IMGUI_TIMELINE_FRAME_INDICES, frameIndicesSize, true);
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
/* Root */
|
||||
_imgui_timeline_element(self, &animation->rootAnimation, NULL, &index, ANM2_ROOT_ANIMATION, NULL, NULL);
|
||||
_imgui_timeline_element(self, animation, &animation->rootAnimation, NULL, &index, ANM2_ROOT_ANIMATION, NULL, NULL);
|
||||
|
||||
/* reverse order */
|
||||
for (auto it = animation->layerAnimations.rbegin(); it != animation->layerAnimations.rend(); it++)
|
||||
@ -768,21 +971,23 @@ imgui_tick(Imgui* self)
|
||||
s32 id = it->first;
|
||||
Anm2LayerAnimation& layer = it->second;
|
||||
|
||||
_imgui_timeline_element(self, &layer, &id, &index, ANM2_LAYER_ANIMATION, &selectedTimelineElementType, &selectedTimelineElementID);
|
||||
_imgui_timeline_element(self, animation, &layer, &id, &index, ANM2_LAYER_ANIMATION, &selectedTimelineElementType, &selectedTimelineElementID);
|
||||
}
|
||||
|
||||
for (auto & [id, null] : animation->nullAnimations)
|
||||
_imgui_timeline_element(self, &null, (s32*)&id, &index, ANM2_NULL_ANIMATION, &selectedTimelineElementType, &selectedTimelineElementID);
|
||||
_imgui_timeline_element(self, animation, &null, (s32*)&id, &index, ANM2_NULL_ANIMATION, &selectedTimelineElementType, &selectedTimelineElementID);
|
||||
|
||||
/* Triggers */
|
||||
_imgui_timeline_element(self, &animation->triggers, NULL, &index, ANM2_TRIGGERS, NULL, NULL);
|
||||
_imgui_timeline_element(self, animation, &animation->triggers, NULL, &index, ANM2_TRIGGERS, NULL, NULL);
|
||||
|
||||
ImGui::EndChild();
|
||||
|
||||
/* Element configuration */
|
||||
if (ImGui::Button(STRING_IMGUI_TIMELINE_ELEMENT_ADD))
|
||||
ImGui::OpenPopup(STRING_IMGUI_TIMELINE_ELEMENT_ADD_MENU);
|
||||
_imgui_tooltip(STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_ADD);
|
||||
|
||||
|
||||
|
||||
if (ImGui::BeginPopup(STRING_IMGUI_TIMELINE_ELEMENT_ADD_MENU))
|
||||
{
|
||||
if (ImGui::Selectable(STRING_IMGUI_TIMELINE_ELEMENT_ADD_MENU_LAYER))
|
||||
@ -798,41 +1003,29 @@ imgui_tick(Imgui* self)
|
||||
|
||||
if
|
||||
(
|
||||
selectedTimelineElementID != -1 &&
|
||||
((selectedTimelineElementType == ANM2_LAYER_ANIMATION) || (selectedTimelineElementType == ANM2_NULL_ANIMATION))
|
||||
ImGui::Button(STRING_IMGUI_TIMELINE_ELEMENT_REMOVE) &&
|
||||
selectedTimelineElementID != -1
|
||||
)
|
||||
{
|
||||
if (ImGui::Button(STRING_IMGUI_TIMELINE_ELEMENT_REMOVE))
|
||||
switch (selectedTimelineElementType)
|
||||
{
|
||||
switch (selectedTimelineElementType)
|
||||
{
|
||||
case ANM2_LAYER_ANIMATION:
|
||||
anm2_layer_remove(self->anm2, selectedTimelineElementID);
|
||||
break;
|
||||
case ANM2_NULL_ANIMATION:
|
||||
anm2_null_remove(self->anm2, selectedTimelineElementID);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
selectedTimelineElementID = -1;
|
||||
selectedTimelineElementType = ANM2_NONE;
|
||||
case ANM2_LAYER_ANIMATION:
|
||||
anm2_layer_remove(self->anm2, selectedTimelineElementID);
|
||||
break;
|
||||
case ANM2_NULL_ANIMATION:
|
||||
anm2_null_remove(self->anm2, selectedTimelineElementID);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
_imgui_tooltip(STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_REMOVE);
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedTimelineElementID = -1;
|
||||
selectedTimelineElementType = ANM2_NONE;
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
_imgui_tooltip(STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_REMOVE);
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
/* Animation playback and frames */
|
||||
static bool isPlaying = false;
|
||||
|
||||
if (isPlaying)
|
||||
@ -853,10 +1046,9 @@ imgui_tick(Imgui* self)
|
||||
_imgui_tooltip(STRING_IMGUI_TOOLTIP_TIMELINE_PAUSE);
|
||||
}
|
||||
|
||||
/*
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button(STRING_IMGUI_TIMELINE_ADD_FRAME))
|
||||
if (ImGui::Button(STRING_IMGUI_TIMELINE_FRAME_ADD))
|
||||
{
|
||||
|
||||
}
|
||||
@ -864,15 +1056,24 @@ imgui_tick(Imgui* self)
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button(STRING_IMGUI_TIMELINE_REMOVE_FRAME))
|
||||
if (ImGui::Button(STRING_IMGUI_TIMELINE_FRAME_REMOVE))
|
||||
{
|
||||
|
||||
}
|
||||
*/
|
||||
_imgui_tooltip(STRING_IMGUI_TOOLTIP_TIMELINE_FRAME_REMOVE);
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::PushItemWidth(IMGUI_TIMELINE_ANIMATION_LENGTH_WIDTH);
|
||||
ImGui::InputInt(STRING_IMGUI_TIMELINE_ANIMATION_LENGTH, &animation->frameNum);
|
||||
ImGui::PopItemWidth();
|
||||
_imgui_tooltip(STRING_IMGUI_TOOLTIP_TIMELINE_ANIMATION_LENGTH);
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
|
||||
if (isFirstTick)
|
||||
isFirstTick = false;
|
||||
}
|
||||
|
||||
void
|
||||
|
49
src/imgui.h
49
src/imgui.h
@ -1,9 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "dialog.h"
|
||||
#include "packed.h"
|
||||
#include "resources.h"
|
||||
#include "preview.h"
|
||||
#include "window.h"
|
||||
#include "input.h"
|
||||
|
||||
#define IMGUI_IMPL_OPENGL_LOADER_CUSTOM
|
||||
#define IMGUI_ENABLE_DOCKING
|
||||
@ -14,23 +15,32 @@
|
||||
|
||||
#define IMGUI_DRAG_SPEED 1.0
|
||||
#define IMGUI_TASKBAR_HEIGHT 32
|
||||
#define IMGUI_TIMELINE_OFFSET_Y 32
|
||||
#define IMGUI_TIMELINE_ANIMATION_LENGTH_WIDTH 200
|
||||
|
||||
static const vec2 IMGUI_TASKBAR_MARGINS = {8, 4};
|
||||
|
||||
static const ImVec2 IMGUI_ANIMATION_PREVIEW_SETTINGS_SIZE = {1280, 64};
|
||||
static const ImVec2 IMGUI_ANIMATION_PREVIEW_SETTINGS_GRID_SIZE = {150, 64};
|
||||
static const ImVec2 IMGUI_ANIMATION_PREVIEW_SETTINGS_ZOOM_SIZE = {150, 64};
|
||||
static const ImVec2 IMGUI_ANIMATION_PREVIEW_SETTINGS_BACKGROUND_SIZE = {150, 64};
|
||||
static const ImVec2 IMGUI_ANIMATION_PREVIEW_SETTINGS_SIZE = {1280, 80};
|
||||
static const ImVec2 IMGUI_ANIMATION_PREVIEW_SETTINGS_CHILD_SIZE = {150, 64};
|
||||
static const ImVec2 IMGUI_ANIMATION_PREVIEW_POSITION = {8, 110};
|
||||
|
||||
static const ImVec2 IMGUI_TIMELINE_ELEMENT_LIST_SIZE = {260, 0};
|
||||
static const ImVec2 IMGUI_TIMELINE_ELEMENT_SIZE = {230, 64};
|
||||
static const ImVec2 IMGUI_TIMELINE_SPRITESHEET_ID_SIZE = {50, 20};
|
||||
static const ImVec2 IMGUI_TIMELINE_SHIFT_ARROWS_SIZE = {24, 48};
|
||||
static const ImVec2 IMGUI_TIMELINE_ELEMENT_NAME_SIZE = {125, 20};
|
||||
static const ImVec2 IMGUI_TIMELINE_FRAME_SIZE = {20, 40};
|
||||
static const ImVec2 IMGUI_TIMELINE_SIZE = {0, 0};
|
||||
static const ImVec2 IMGUI_TIMELINE_ELEMENTS_BAR_SIZE = {300, 32};
|
||||
static const ImVec2 IMGUI_TIMELINE_ELEMENTS_TIMELINE_SIZE = {0, 40};
|
||||
static const ImVec2 IMGUI_TIMELINE_FRAME_INDICES_SIZE = {0, 32};
|
||||
static const ImVec2 IMGUI_TIMELINE_ELEMENT_LIST_SIZE = {300, 0};
|
||||
static const ImVec2 IMGUI_TIMELINE_ELEMENT_SIZE = {300, 40};
|
||||
static const ImVec2 IMGUI_TIMELINE_SPRITESHEET_ID_SIZE = {40, 20};
|
||||
static const ImVec2 IMGUI_TIMELINE_SHIFT_ARROWS_SIZE = {64, 40};
|
||||
static const ImVec2 IMGUI_TIMELINE_ELEMENT_NAME_SIZE = {85, 20};
|
||||
|
||||
static const ImVec2 IMGUI_SPRITESHEET_SIZE = {0, 150};
|
||||
static const ImVec2 IMGUI_SPRITESHEET_PREVIEW_SIZE = {100, 100};
|
||||
static const ImVec2 IMGUI_ICON_SIZE = {16, 16};
|
||||
static const ImVec2 IMGUI_ICON_BUTTON_SIZE = {22, 22};
|
||||
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_DUMMY_SIZE = {1, 1};
|
||||
|
||||
#define IMGUI_TIMELINE_SHIFT_ARROWS_WIDTH (IMGUI_TIMELINE_SHIFT_ARROWS_SIZE.x * 1.35)
|
||||
@ -38,13 +48,26 @@ static const ImVec2 IMGUI_DUMMY_SIZE = {1, 1};
|
||||
struct Imgui
|
||||
{
|
||||
Dialog* dialog = NULL;
|
||||
Packed* packed = NULL;
|
||||
Resources* resources = NULL;
|
||||
Input* input = NULL;
|
||||
Anm2* anm2 = NULL;
|
||||
Preview* preview = NULL;
|
||||
SDL_Window* window = NULL;
|
||||
SDL_GLContext* glContext = NULL;
|
||||
};
|
||||
|
||||
void imgui_init(SDL_Window* window, SDL_GLContext glContext);
|
||||
void imgui_init
|
||||
(
|
||||
Imgui* self,
|
||||
Dialog* dialog,
|
||||
Resources* resources,
|
||||
Input* input,
|
||||
Anm2* anm2,
|
||||
Preview* preview,
|
||||
SDL_Window* window,
|
||||
SDL_GLContext* glContext
|
||||
);
|
||||
|
||||
void imgui_tick(Imgui* self);
|
||||
void imgui_draw(Imgui* self);
|
||||
void imgui_free(Imgui* self);
|
||||
|
54
src/input.cpp
Normal file
54
src/input.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
#include "input.h"
|
||||
|
||||
static void _mouse_tick(Mouse* self);
|
||||
|
||||
static void
|
||||
_mouse_tick(Mouse* self)
|
||||
{
|
||||
s32 state;
|
||||
SDL_Event event;
|
||||
|
||||
memcpy(&self->previous, &self->current, sizeof(bool) * MOUSE_COUNT);
|
||||
memset(&self->current, '\0', sizeof(bool) * MOUSE_COUNT);
|
||||
|
||||
state = SDL_GetMouseState(NULL, NULL);
|
||||
|
||||
if (state & SDL_BUTTON_LMASK != 0)
|
||||
{
|
||||
self->current[MOUSE_LEFT] = true;
|
||||
}
|
||||
|
||||
if (state & SDL_BUTTON_RMASK != 0)
|
||||
{
|
||||
self->current[MOUSE_RIGHT] = true;
|
||||
}
|
||||
|
||||
SDL_GetMouseState(&self->position.x, &self->position.y);
|
||||
|
||||
self->delta = self->position - self->oldPosition;
|
||||
self->oldPosition = self->position;
|
||||
}
|
||||
|
||||
bool
|
||||
mouse_press(Mouse* self, MouseType type)
|
||||
{
|
||||
return (self->current[type] && !self->previous[type]);
|
||||
}
|
||||
|
||||
bool
|
||||
mouse_held(Mouse* self, MouseType type)
|
||||
{
|
||||
return (self->current[type] && self->previous[type]);
|
||||
}
|
||||
|
||||
bool
|
||||
mouse_release(Mouse* self, MouseType type)
|
||||
{
|
||||
return (!self->current[type] && self->previous[type]);
|
||||
}
|
||||
|
||||
void
|
||||
input_tick(Input* self)
|
||||
{
|
||||
_mouse_tick(&self->mouse);
|
||||
}
|
35
src/input.h
Normal file
35
src/input.h
Normal file
@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include "COMMON.h"
|
||||
|
||||
#define MOUSE_COUNT (MOUSE_RIGHT + 1)
|
||||
enum MouseType
|
||||
{
|
||||
MOUSE_LEFT,
|
||||
MOUSE_RIGHT
|
||||
};
|
||||
|
||||
enum InputType
|
||||
{
|
||||
INPUT_MOUSE_CLICK
|
||||
};
|
||||
|
||||
struct Mouse
|
||||
{
|
||||
bool current[MOUSE_COUNT];
|
||||
bool previous[MOUSE_COUNT];
|
||||
vec2 position = {-1, -1};
|
||||
vec2 oldPosition = {-1, -1};
|
||||
vec2 delta = {-1, -1};
|
||||
s32 wheelDeltaY = 0;
|
||||
};
|
||||
|
||||
struct Input
|
||||
{
|
||||
Mouse mouse;
|
||||
};
|
||||
|
||||
bool mouse_press(Mouse* self, MouseType type);
|
||||
bool mouse_held(Mouse* self, MouseType type);
|
||||
bool mouse_release(Mouse* self, MouseType type);
|
||||
void input_tick(Input* self);
|
@ -1,17 +0,0 @@
|
||||
#include "packed.h"
|
||||
|
||||
/* Loads in packed data */
|
||||
void
|
||||
packed_init(Packed* self)
|
||||
{
|
||||
for (s32 i = 0; i < PACKED_TEXTURE_COUNT; i++)
|
||||
texture_from_data_init(&self->textures[i], (u8*)PACKED_TEXTURE_DATA[i].data, PACKED_TEXTURE_DATA[i].length);
|
||||
}
|
||||
|
||||
/* Frees packed data */
|
||||
void
|
||||
packed_free(Packed* self)
|
||||
{
|
||||
for (s32 i = 0; i < PACKED_TEXTURE_COUNT; i++)
|
||||
texture_free(&self->textures[i]);
|
||||
}
|
12
src/packed.h
12
src/packed.h
@ -1,12 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "PACKED.h"
|
||||
#include "texture.h"
|
||||
|
||||
struct Packed
|
||||
{
|
||||
Texture textures[PACKED_TEXTURE_COUNT];
|
||||
};
|
||||
|
||||
void packed_init(Packed* self);
|
||||
void packed_free(Packed* self);
|
149
src/preview.cpp
149
src/preview.cpp
@ -1,10 +1,69 @@
|
||||
#include "preview.h"
|
||||
|
||||
static void _preview_axis_set(Preview* self);
|
||||
static void _preview_grid_set(Preview* self);
|
||||
|
||||
/* Initializes the preview */
|
||||
void
|
||||
preview_init(Preview* self)
|
||||
static void
|
||||
_preview_axis_set(Preview* self)
|
||||
{
|
||||
glBindVertexArray(self->axisVAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, self->axisVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(PREVIEW_AXIS_VERTICES), PREVIEW_AXIS_VERTICES, GL_STATIC_DRAW);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
static void
|
||||
_preview_grid_set(Preview* self)
|
||||
{
|
||||
std::vector<f32> vertices;
|
||||
|
||||
s32 verticalLineCount = PREVIEW_SIZE.x / self->gridSize.x;
|
||||
s32 horizontalLineCount = PREVIEW_SIZE.y / self->gridSize.y;
|
||||
|
||||
/* Vertical */
|
||||
for (s32 i = 0; i <= verticalLineCount; i++)
|
||||
{
|
||||
s32 x = i * self->gridSize.x;
|
||||
f32 normX = (2.0f * x) / PREVIEW_SIZE.x - 1.0f;
|
||||
|
||||
vertices.push_back(normX);
|
||||
vertices.push_back(-1.0f);
|
||||
vertices.push_back(normX);
|
||||
vertices.push_back(1.0f);
|
||||
}
|
||||
|
||||
/* Horizontal */
|
||||
for (s32 i = 0; i <= horizontalLineCount; i++)
|
||||
{
|
||||
s32 y = i * self->gridSize.y;
|
||||
f32 normY = (2.0f * y) / PREVIEW_SIZE.y - 1.0f;
|
||||
|
||||
vertices.push_back(-1.0f);
|
||||
vertices.push_back(normY);
|
||||
vertices.push_back(1.0f);
|
||||
vertices.push_back(normY);
|
||||
}
|
||||
|
||||
self->gridVertexCount = (s32)vertices.size();
|
||||
|
||||
glBindVertexArray(self->gridVAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, self->gridVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_DYNAMIC_DRAW);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(f32), (void*)0);
|
||||
}
|
||||
|
||||
void
|
||||
preview_init(Preview* self, Resources* resources, Input* input)
|
||||
{
|
||||
self->resources = resources;
|
||||
self->input = input;
|
||||
|
||||
glGenFramebuffers(1, &self->fbo);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, self->fbo);
|
||||
@ -23,18 +82,98 @@ preview_init(Preview* self)
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, self->rbo);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
glGenVertexArrays(1, &self->axisVAO);
|
||||
glGenBuffers(1, &self->axisVBO);
|
||||
|
||||
glGenVertexArrays(1, &self->gridVAO);
|
||||
glGenBuffers(1, &self->gridVBO);
|
||||
|
||||
_preview_axis_set(self);
|
||||
_preview_grid_set(self);
|
||||
}
|
||||
|
||||
void
|
||||
preview_tick(Preview* self)
|
||||
{
|
||||
self->zoom = CLAMP(self->zoom, PREVIEW_ZOOM_MIN, PREVIEW_ZOOM_MAX);
|
||||
self->oldGridSize = self->gridSize;
|
||||
}
|
||||
|
||||
void
|
||||
preview_draw(Preview* self)
|
||||
{
|
||||
GLuint shader = self->resources->shaders[SHADER];
|
||||
float zoomFactor = self->zoom / 100.0f;
|
||||
|
||||
/* Convert pan to pixels */
|
||||
glm::vec2 ndcPan = glm::vec2(
|
||||
self->pan.x / (PREVIEW_SIZE.x / 2.0f),
|
||||
-self->pan.y / (PREVIEW_SIZE.y / 2.0f)
|
||||
);
|
||||
|
||||
/* Transformation matrix */
|
||||
glm::mat4 transform = glm::translate(glm::mat4(1.0f), glm::vec3(ndcPan, 0.0f));
|
||||
transform = glm::scale(transform, glm::vec3(zoomFactor, zoomFactor, 1.0f));
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, self->fbo);
|
||||
glViewport(0, 0, PREVIEW_SIZE.x, PREVIEW_SIZE.y);
|
||||
|
||||
glClearColor(self->color.r, self->color.g, self->color.b, self->color.a);
|
||||
glClearColor
|
||||
(
|
||||
self->backgroundColor.r,
|
||||
self->backgroundColor.g,
|
||||
self->backgroundColor.b,
|
||||
self->backgroundColor.a
|
||||
);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0); // unbind
|
||||
glUseProgram(shader);
|
||||
glUniformMatrix4fv(glGetUniformLocation(shader, SHADER_UNIFORM_TRANSFORM), 1, GL_FALSE, (f32*)value_ptr(transform));
|
||||
|
||||
if (self->isGrid)
|
||||
{
|
||||
if (self->gridSize != self->oldGridSize)
|
||||
_preview_grid_set(self);
|
||||
|
||||
glBindVertexArray(self->gridVAO);
|
||||
|
||||
glUniform4f
|
||||
(
|
||||
glGetUniformLocation(shader, SHADER_UNIFORM_COLOR),
|
||||
self->gridColor.r, self->gridColor.g, self->gridColor.b, self->gridColor.a
|
||||
);
|
||||
|
||||
glDrawArrays(GL_LINES, 0, self->gridVertexCount);
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
if (self->isAxis)
|
||||
{
|
||||
glBindVertexArray(self->axisVAO);
|
||||
|
||||
/* Axes */
|
||||
glUniform4f
|
||||
(
|
||||
glGetUniformLocation(shader, SHADER_UNIFORM_COLOR),
|
||||
self->axisColor.r, self->axisColor.g, self->axisColor.b, self->axisColor.a
|
||||
);
|
||||
glDrawArrays(GL_LINES, 0, 2);
|
||||
|
||||
glUniform4f
|
||||
(
|
||||
glGetUniformLocation(shader, SHADER_UNIFORM_COLOR),
|
||||
self->axisColor.r, self->axisColor.g, self->axisColor.b, self->axisColor.a
|
||||
);
|
||||
glDrawArrays(GL_LINES, 2, 2);
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
glUseProgram(0);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1,26 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
#include "texture.h"
|
||||
#include "resources.h"
|
||||
#include "input.h"
|
||||
|
||||
static const ivec2 PREVIEW_SIZE = {1280, 720};
|
||||
static const ivec2 PREVIEW_SIZE = {960, 720};
|
||||
static const ivec2 PREVIEW_CENTER = {0, 0};
|
||||
|
||||
#define PREVIEW_ZOOM_MIN 0
|
||||
#define PREVIEW_ZOOM_MIN 1
|
||||
#define PREVIEW_ZOOM_MAX 400
|
||||
#define PREVIEW_GRID_MIN 0
|
||||
#define PREVIEW_GRID_MAX 20
|
||||
#define PREVIEW_GRID_MIN 1
|
||||
#define PREVIEW_GRID_MAX 50
|
||||
#define PREVIEW_ZOOM_STEP 10
|
||||
|
||||
static const f32 PREVIEW_AXIS_VERTICES[] =
|
||||
{
|
||||
-1.0f, 0.0f,
|
||||
1.0f, 0.0f,
|
||||
0.0f, -1.0f,
|
||||
0.0f, 1.0f
|
||||
};
|
||||
|
||||
struct Preview
|
||||
{
|
||||
GLuint texture;
|
||||
GLuint fbo;
|
||||
GLuint rbo;
|
||||
bool isGrid;
|
||||
GLuint gridVAO;
|
||||
GLuint gridVBO;
|
||||
GLuint axisVAO;
|
||||
GLuint axisVBO;
|
||||
Input* input;
|
||||
Resources* resources;
|
||||
bool isGrid = false;
|
||||
bool isAxis = true;
|
||||
ivec2 viewport = PREVIEW_SIZE;
|
||||
f32 zoom = 100;
|
||||
vec2 pan = PREVIEW_CENTER;
|
||||
ivec2 gridSize = {10, 10};
|
||||
vec4 color = {0.69, 0.69, 0.69, 1.0f};
|
||||
vec4 gridColor = {0.35, 0.35, 0.35, 1.0f};
|
||||
ivec2 oldGridSize = {-1, -1};
|
||||
s32 gridVertexCount = -1;
|
||||
vec4 backgroundColor = {0.113, 0.184, 0.286, 1.0f};
|
||||
vec4 gridColor = {1.0, 1.0, 1.0, 0.125f};
|
||||
vec4 axisColor = {1.0, 1.0, 1.0, 0.5f};
|
||||
};
|
||||
|
||||
void preview_init(Preview* self);
|
||||
void preview_init(Preview* self, Resources* resources, Input* input);
|
||||
void preview_draw(Preview* self);
|
||||
void preview_tick(Preview* self);
|
||||
void preview_free(Preview* self);
|
||||
|
33
src/resources.cpp
Normal file
33
src/resources.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
#include "resources.h"
|
||||
|
||||
/* Loads in resources */
|
||||
void
|
||||
resources_init(Resources* self)
|
||||
{
|
||||
/* Textures */
|
||||
for (s32 i = 0; i < TEXTURE_COUNT; i++)
|
||||
texture_from_data_init(&self->textures[i], (u8*)TEXTURE_DATA[i].data, TEXTURE_DATA[i].length);
|
||||
|
||||
for (s32 i = 0; i < SHADER_COUNT; i++)
|
||||
shader_init(&self->shaders[i], SHADER_DATA[i].vertex, SHADER_DATA[i].fragment);
|
||||
}
|
||||
|
||||
/* Frees resources*/
|
||||
void
|
||||
resources_free(Resources* self)
|
||||
{
|
||||
for (s32 i = 0; i < TEXTURE_COUNT; i++)
|
||||
texture_free(&self->textures[i]);
|
||||
|
||||
for (s32 i = 0; i < SHADER_COUNT; i++)
|
||||
shader_free(&self->shaders[i]);
|
||||
|
||||
resources_loaded_textures_free(self);
|
||||
}
|
||||
|
||||
void
|
||||
resources_loaded_textures_free(Resources* self)
|
||||
{
|
||||
for (auto & [id, texture] : self->loadedTextures)
|
||||
texture_free(&self->textures[id]);
|
||||
}
|
16
src/resources.h
Normal file
16
src/resources.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "RESOURCES.h"
|
||||
#include "texture.h"
|
||||
#include "shader.h"
|
||||
|
||||
struct Resources
|
||||
{
|
||||
Texture textures[TEXTURE_COUNT];
|
||||
GLuint shaders[SHADER_COUNT];
|
||||
std::map<s32, Texture> loadedTextures;
|
||||
};
|
||||
|
||||
void resources_init(Resources* self);
|
||||
void resources_free(Resources* self);
|
||||
void resources_loaded_textures_free(Resources* self);
|
@ -1,24 +1,24 @@
|
||||
#include "shader.h"
|
||||
|
||||
static bool _shader_compile(GLuint handle, const char* text);
|
||||
static bool _shader_compile(GLuint* self, const char* text);
|
||||
|
||||
static bool
|
||||
_shader_compile(GLuint handle, const char* text)
|
||||
_shader_compile(GLuint* self, const char* text)
|
||||
{
|
||||
char compileLog[SHADER_BUFFER_MAX];
|
||||
s32 isCompile;
|
||||
|
||||
const GLchar* source = text;
|
||||
|
||||
glShaderSource(handle, 1, &source, NULL);
|
||||
glShaderSource(*self, 1, &source, NULL);
|
||||
|
||||
glCompileShader(handle);
|
||||
glGetShaderiv(handle, GL_COMPILE_STATUS, &isCompile);
|
||||
glCompileShader(*self);
|
||||
glGetShaderiv(*self, GL_COMPILE_STATUS, &isCompile);
|
||||
|
||||
if (!isCompile)
|
||||
{
|
||||
glGetShaderInfoLog(handle, SHADER_BUFFER_MAX, NULL, compileLog);
|
||||
printf(STRING_ERROR_SHADER_INIT, handle, compileLog);
|
||||
glGetShaderInfoLog(*self, SHADER_BUFFER_MAX, NULL, compileLog);
|
||||
printf(STRING_ERROR_SHADER_INIT, *self, compileLog);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -26,47 +26,39 @@ _shader_compile(GLuint handle, const char* text)
|
||||
}
|
||||
|
||||
bool
|
||||
shader_init(Shader* self, const char* vertex, const char* fragment)
|
||||
shader_init(GLuint* self, const char* vertex, const char* fragment)
|
||||
{
|
||||
GLuint vertexHandle;
|
||||
GLuint fragmentHandle;
|
||||
bool isSuccess;
|
||||
|
||||
memset(self, '\0', sizeof(Shader));
|
||||
|
||||
vertexHandle = glCreateShader(GL_VERTEX_SHADER);
|
||||
fragmentHandle = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
|
||||
if
|
||||
(
|
||||
!_shader_compile(vertexHandle, vertex) ||
|
||||
!_shader_compile(fragmentHandle, fragment)
|
||||
!_shader_compile(&vertexHandle, vertex) ||
|
||||
!_shader_compile(&fragmentHandle, fragment)
|
||||
)
|
||||
return false;
|
||||
|
||||
self->handle = glCreateProgram();
|
||||
*self = glCreateProgram();
|
||||
|
||||
glAttachShader(self->handle, vertexHandle);
|
||||
glAttachShader(self->handle, fragmentHandle);
|
||||
glAttachShader(*self, vertexHandle);
|
||||
glAttachShader(*self, fragmentHandle);
|
||||
|
||||
glLinkProgram(self->handle);
|
||||
glLinkProgram(*self);
|
||||
|
||||
glDeleteShader(vertexHandle);
|
||||
glDeleteShader(fragmentHandle);
|
||||
|
||||
printf(STRING_INFO_SHADER_INIT, self->handle);
|
||||
printf(STRING_INFO_SHADER_INIT, *self);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
shader_use(Shader* self)
|
||||
shader_free(GLuint* self)
|
||||
{
|
||||
glUseProgram(self->handle);
|
||||
}
|
||||
|
||||
void
|
||||
shader_free(Shader* self)
|
||||
{
|
||||
glDeleteProgram(self->handle);
|
||||
}
|
||||
glDeleteProgram(*self);
|
||||
}
|
10
src/shader.h
10
src/shader.h
@ -4,11 +4,5 @@
|
||||
|
||||
#define SHADER_BUFFER_MAX 2048
|
||||
|
||||
struct Shader
|
||||
{
|
||||
GLuint handle = 0;
|
||||
};
|
||||
|
||||
bool shader_init(Shader* self, const char* vertex, const char* fragment);
|
||||
void shader_free(Shader* self);
|
||||
void shader_use(Shader* self);
|
||||
bool shader_init(GLuint* self, const char* vertex, const char* fragment);
|
||||
void shader_free(GLuint* self);
|
@ -7,15 +7,30 @@ static void
|
||||
_tick(State* state)
|
||||
{
|
||||
SDL_Event event;
|
||||
SDL_MouseWheelEvent* mouseWheelEvent;
|
||||
|
||||
state->input.mouse.wheelDeltaY = 0;
|
||||
|
||||
while(SDL_PollEvent(&event))
|
||||
{
|
||||
ImGui_ImplSDL3_ProcessEvent(&event);
|
||||
ImGui_ImplSDL3_ProcessEvent(&event);
|
||||
|
||||
if (event.type == SDL_EVENT_QUIT)
|
||||
state->isRunning = false;
|
||||
switch (event.type)
|
||||
{
|
||||
case SDL_EVENT_QUIT:
|
||||
state->isRunning = false;
|
||||
break;
|
||||
case SDL_EVENT_MOUSE_WHEEL:
|
||||
mouseWheelEvent = &event.wheel;
|
||||
state->input.mouse.wheelDeltaY = mouseWheelEvent->y;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
input_tick(&state->input);
|
||||
preview_tick(&state->preview);
|
||||
dialog_tick(&state->dialog);
|
||||
imgui_tick(&state->imgui);
|
||||
}
|
||||
@ -32,8 +47,6 @@ _draw(State* state)
|
||||
void
|
||||
init(State* state)
|
||||
{
|
||||
Shader shader;
|
||||
|
||||
printf(STRING_INFO_INIT);
|
||||
|
||||
if (!SDL_Init(SDL_INIT_VIDEO))
|
||||
@ -64,31 +77,34 @@ init(State* state)
|
||||
|
||||
glewInit();
|
||||
|
||||
preview_init(&state->preview);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
printf(STRING_INFO_GLEW_INIT);
|
||||
|
||||
packed_init(&state->packed);
|
||||
|
||||
resources_init(&state->resources);
|
||||
dialog_init(&state->dialog, &state->anm2, &state->resources);
|
||||
|
||||
preview_init(&state->preview, &state->resources, &state->input);
|
||||
|
||||
if (state->isArgument)
|
||||
anm2_deserialize(&state->anm2, state->argument);
|
||||
anm2_deserialize(&state->anm2, &state->resources, state->argument);
|
||||
else
|
||||
anm2_new(&state->anm2);
|
||||
|
||||
window_title_from_anm2_set(state->window, &state->anm2);
|
||||
|
||||
state->imgui =
|
||||
{
|
||||
imgui_init
|
||||
(
|
||||
&state->imgui,
|
||||
&state->dialog,
|
||||
&state->packed,
|
||||
&state->anm2,
|
||||
&state->resources,
|
||||
&state->input,
|
||||
&state->anm2,
|
||||
&state->preview,
|
||||
state->window
|
||||
};
|
||||
|
||||
imgui_init(state->window, state->glContext);
|
||||
|
||||
state->dialog.anm2 = &state->anm2;
|
||||
state->window,
|
||||
&state->glContext
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
@ -104,7 +120,6 @@ loop(State* state)
|
||||
SDL_Delay(TICK_DELAY - (state->tick - state->lastTick));
|
||||
|
||||
_tick(state);
|
||||
|
||||
_draw(state);
|
||||
|
||||
state->lastTick = state->tick;
|
||||
@ -116,13 +131,11 @@ quit(State* state)
|
||||
{
|
||||
imgui_free(&state->imgui);
|
||||
preview_free(&state->preview);
|
||||
packed_free(&state->packed);
|
||||
resources_free(&state->resources);
|
||||
|
||||
SDL_GL_DestroyContext(state->glContext);
|
||||
SDL_Quit();
|
||||
|
||||
printf(STRING_INFO_SDL_QUIT);
|
||||
|
||||
printf(STRING_INFO_QUIT);
|
||||
}
|
||||
|
||||
|
@ -14,10 +14,11 @@ struct State
|
||||
SDL_Renderer* renderer;
|
||||
SDL_GLContext glContext;
|
||||
Imgui imgui;
|
||||
Input input;
|
||||
Dialog dialog;
|
||||
Preview preview;
|
||||
Anm2 anm2;
|
||||
Packed packed;
|
||||
Resources resources;
|
||||
char argument[PATH_MAX] = STRING_EMPTY;
|
||||
bool isArgument = false;
|
||||
u64 tick = 0;
|
||||
|
@ -63,4 +63,4 @@ texture_free(Texture* self)
|
||||
{
|
||||
glDeleteTextures(1, &self->handle);
|
||||
memset(self, '\0', sizeof(Texture));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user