visuals and a lot of other things

This commit is contained in:
2025-06-26 08:48:42 -04:00
parent ea2e7e918c
commit 6d488fce1e
21 changed files with 2315 additions and 728 deletions

3
.gitmodules vendored
View File

@@ -8,3 +8,6 @@
[submodule "include/tinyxml2"] [submodule "include/tinyxml2"]
path = include/tinyxml2 path = include/tinyxml2
url = https://github.com/leethomason/tinyxml2 url = https://github.com/leethomason/tinyxml2
[submodule "include/inih"]
path = include/inih
url = https://github.com/benhoyt/inih

View File

@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.10) cmake_minimum_required(VERSION 3.10)
project(anm2ed CXX) project(anm2ed C CXX)
# Gather project sources # Gather project sources
file(GLOB SOURCES file(GLOB SOURCES
@@ -10,12 +10,13 @@ file(GLOB SOURCES
"include/imgui/backends/imgui_impl_sdl3.cpp" "include/imgui/backends/imgui_impl_sdl3.cpp"
"include/imgui/backends/imgui_impl_opengl3.cpp" "include/imgui/backends/imgui_impl_opengl3.cpp"
"include/tinyxml2/tinyxml2.cpp" "include/tinyxml2/tinyxml2.cpp"
"include/inih/ini.c"
"${PROJECT_SOURCE_DIR}/src/*.cpp" "${PROJECT_SOURCE_DIR}/src/*.cpp"
) )
add_executable(${PROJECT_NAME} ${SOURCES}) add_executable(${PROJECT_NAME} ${SOURCES})
target_include_directories(${PROJECT_NAME} PRIVATE include include/imgui include/tinyxml2 src) target_include_directories(${PROJECT_NAME} PRIVATE include include/imgui include/tinyxml2 include/inih src)
set(CMAKE_CXX_FLAGS "-g -O2 -std=c++23 -Wall -Wextra -pedantic -Wno-unused-variable -Wno-unused-parameter -Wno-ignored-qualifiers -Wno-parentheses -Wno-unused-function -Wno-class-memaccess -Wno-delete-incomplete") set(CMAKE_CXX_FLAGS "-g -O2 -std=c++23 -Wall -Wextra -pedantic -Wno-unused-variable -Wno-unused-parameter -Wno-ignored-qualifiers -Wno-parentheses -Wno-unused-function -Wno-class-memaccess -Wno-delete-incomplete")

69
settings.ini Normal file
View File

@@ -0,0 +1,69 @@
[Settings]
panX=-521.000000
panY=258.000000
# Dear ImGui
[Window][Window]
Pos=0,32
Size=1918,1030
Collapsed=0
[Window][Debug##Default]
Pos=60,60
Size=400,400
Collapsed=0
[Window][Animations]
Pos=1197,40
Size=485,342
Collapsed=0
DockId=0x00000005,0
[Window][Events]
Pos=1197,384
Size=485,345
Collapsed=0
DockId=0x00000006,0
[Window][Spritesheets]
Pos=1684,40
Size=226,689
Collapsed=0
DockId=0x00000002,0
[Window][Spritesheet Editor]
Pos=60,60
Size=32,35
Collapsed=0
[Window][Timeline]
Pos=8,731
Size=1902,323
Collapsed=0
DockId=0x0000000A,0
[Window][Frame Properties]
Pos=890,40
Size=305,689
Collapsed=0
DockId=0x00000008,0
[Window][Animation Preview]
Pos=8,40
Size=880,689
Collapsed=0
DockId=0x00000007,0
[Docking][Data]
DockSpace ID=0xFB691B2E Window=0xFA2EAA04 Pos=8,40 Size=1902,1014 Split=Y Selected=0x024430EF
DockNode ID=0x00000009 Parent=0xFB691B2E SizeRef=1902,689 Split=X
DockNode ID=0x00000001 Parent=0x00000009 SizeRef=1674,1014 Split=X Selected=0x024430EF
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=1187,1014 Split=X Selected=0x024430EF
DockNode ID=0x00000007 Parent=0x00000003 SizeRef=880,1014 CentralNode=1 Selected=0x024430EF
DockNode ID=0x00000008 Parent=0x00000003 SizeRef=305,1014 Selected=0x754E368F
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=485,1014 Split=Y Selected=0x8A65D963
DockNode ID=0x00000005 Parent=0x00000004 SizeRef=485,504 Selected=0xC1986EE2
DockNode ID=0x00000006 Parent=0x00000004 SizeRef=485,508 Selected=0x8A65D963
DockNode ID=0x00000002 Parent=0x00000009 SizeRef=226,1014 Selected=0x4EFD0020
DockNode ID=0x0000000A Parent=0xFB691B2E SizeRef=1902,323 Selected=0x4F89F0DC

View File

@@ -11,6 +11,7 @@
#include <math.h> #include <math.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
@@ -18,6 +19,7 @@
#include <algorithm> #include <algorithm>
#include <filesystem> #include <filesystem>
#include <iostream>
#include <map> #include <map>
#include <ranges> #include <ranges>
#include <vector> #include <vector>
@@ -46,6 +48,13 @@ using namespace glm; // fuck you
#define MAX(x, max) (x > max ? max : x) #define MAX(x, max) (x > max ? max : x)
#define CLAMP(x, min, max) (MIN(MAX(x, max), min)) #define CLAMP(x, min, max) (MIN(MAX(x, max), min))
#define COLOR_FLOAT_TO_INT(x) (static_cast<int>((x) * 255.0f))
#define COLOR_INT_TO_FLOAT(x) ((x) / 255.0f)
#define TICK_DELAY 33.3f
#define SECOND 1000.0f
#define TICK_RATE (SECOND / TICK_DELAY)
static inline const char* enum_to_string(const char* arr[], s32 count, s32 index) { return (index >= 0 && index < count) ? arr[index] : "undefined"; } static inline const char* enum_to_string(const char* arr[], s32 count, s32 index) { return (index >= 0 && index < count) ? arr[index] : "undefined"; }
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 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 bool string_to_bool(const char* str) { if (strcmp(str, "true") == 0) return true; return false; }

View File

@@ -9,6 +9,13 @@ struct TextureData
u32 length; u32 length;
}; };
static const unsigned char texture_dummy[] =
{
0xFF
};
static const unsigned int texture_dummy_len = 1;
static const unsigned char texture_eye_closed[] = { static const unsigned char texture_eye_closed[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10,
@@ -266,10 +273,154 @@ static const unsigned char texture_arrow_down[] = {
0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
}; };
static const unsigned int texture_arrow_down_len = 153; static const unsigned int texture_arrow_down_len = 153;
static const unsigned char texture_frame[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x28,
0x08, 0x06, 0x00, 0x00, 0x00, 0xf7, 0xda, 0x7a, 0xa1, 0x00, 0x00, 0x00,
0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x5c, 0x46, 0x00, 0x00, 0x5c,
0x46, 0x01, 0x14, 0x94, 0x43, 0x41, 0x00, 0x00, 0x00, 0x29, 0x49, 0x44,
0x41, 0x54, 0x48, 0xc7, 0x63, 0x68, 0x68, 0x68, 0xf8, 0xcf, 0x40, 0x01,
0x60, 0x62, 0xa0, 0x10, 0x0c, 0xbc, 0x01, 0xa3, 0x60, 0x14, 0x8c, 0x82,
0x51, 0x30, 0x0a, 0x46, 0xc1, 0x28, 0x18, 0x7e, 0x60, 0xb4, 0x89, 0x43,
0xb9, 0x01, 0x00, 0xc1, 0xdf, 0x05, 0x0d, 0xfb, 0xcb, 0xa2, 0x51, 0x00,
0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned int texture_frame_len = 119;
#define TEXTURE_COUNT (TEXTURE_ARROW_DOWN + 1) static const unsigned char texture_frame_alternate[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x28,
0x08, 0x06, 0x00, 0x00, 0x00, 0xf7, 0xda, 0x7a, 0xa1, 0x00, 0x00, 0x00,
0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x5c, 0x46, 0x00, 0x00, 0x5c,
0x46, 0x01, 0x14, 0x94, 0x43, 0x41, 0x00, 0x00, 0x00, 0x2a, 0x49, 0x44,
0x41, 0x54, 0x48, 0xc7, 0xed, 0xcc, 0x31, 0x0d, 0x00, 0x30, 0x0c, 0x03,
0xb0, 0xa8, 0xc8, 0xc2, 0x9f, 0xd4, 0x06, 0xa2, 0x4f, 0x0f, 0x1b, 0x80,
0xd3, 0xf6, 0x65, 0x61, 0xb2, 0x24, 0x10, 0x08, 0x04, 0x02, 0x81, 0x40,
0x20, 0xb8, 0x18, 0x7c, 0x4d, 0xb9, 0x02, 0x0e, 0x6e, 0xb1, 0x5c, 0xc5,
0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned int texture_frame_alternate_len = 120;
static const unsigned char texture_picker[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x28,
0x08, 0x06, 0x00, 0x00, 0x00, 0xf7, 0xda, 0x7a, 0xa1, 0x00, 0x00, 0x00,
0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x5c, 0x46, 0x00, 0x00, 0x5c,
0x46, 0x01, 0x14, 0x94, 0x43, 0x41, 0x00, 0x00, 0x00, 0x58, 0x49, 0x44,
0x41, 0x54, 0x48, 0xc7, 0xed, 0xd6, 0x3b, 0x0e, 0x00, 0x20, 0x08, 0x44,
0x41, 0x35, 0xde, 0x1b, 0x38, 0xb9, 0x06, 0x2b, 0x13, 0xbf, 0x88, 0xe5,
0x6e, 0x61, 0xc7, 0xc4, 0xf2, 0x45, 0x66, 0x2e, 0xc1, 0xb1, 0x14, 0x9c,
0xcb, 0xfa, 0x10, 0xd1, 0xd3, 0xb1, 0x88, 0xf8, 0x7f, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0c, 0xb4, 0x69, 0x64, 0x58, 0x37,
0x84, 0x89, 0x05, 0x59, 0x56, 0xcd, 0x0d, 0x72, 0x4c, 0xa2, 0x1d, 0x72,
0xdd, 0x53, 0x33, 0xc4, 0x1c, 0x63, 0x3d, 0xf2, 0x5c, 0x72, 0x7a, 0x78,
0x3a, 0xae, 0xf6, 0x35, 0xd0, 0x0d, 0x0b, 0xf2, 0x1e, 0xa3, 0x00, 0x00,
0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static unsigned int texture_picker_len = 166;
static const unsigned char texture_interpolated_frame_icon[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08,
0x08, 0x06, 0x00, 0x00, 0x00, 0xc4, 0x0f, 0xbe, 0x8b, 0x00, 0x00, 0x00,
0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x5c, 0x46, 0x00, 0x00, 0x5c,
0x46, 0x01, 0x14, 0x94, 0x43, 0x41, 0x00, 0x00, 0x00, 0x24, 0x49, 0x44,
0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0x20, 0x00, 0x18, 0x61, 0x8c, 0xff,
0x40, 0x80, 0x22, 0x01, 0x04, 0x70, 0x05, 0xe8, 0x92, 0xc8, 0x8a, 0x98,
0x08, 0x59, 0x41, 0xb9, 0x02, 0x82, 0x8e, 0x24, 0x08, 0x00, 0x53, 0x98,
0x0c, 0x0a, 0x09, 0x30, 0x65, 0xd2, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45,
0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned int texture_interpolated_frame_icon_len = 114;
static const unsigned char texture_uninterpolated_frame_icon[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08,
0x08, 0x06, 0x00, 0x00, 0x00, 0xc4, 0x0f, 0xbe, 0x8b, 0x00, 0x00, 0x00,
0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x5c, 0x46, 0x00, 0x00, 0x5c,
0x46, 0x01, 0x14, 0x94, 0x43, 0x41, 0x00, 0x00, 0x00, 0x1c, 0x49, 0x44,
0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0x20, 0x00, 0x18, 0x41, 0xc4, 0x7f,
0x20, 0xc0, 0x2a, 0x09, 0x04, 0x4c, 0x84, 0x4c, 0x18, 0x0c, 0x0a, 0x08,
0x02, 0x00, 0x88, 0xe4, 0x04, 0x0c, 0x6a, 0xae, 0x5d, 0xa6, 0x00, 0x00,
0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned int texture_uninterpolated_frame_icon_len = 106;
static const unsigned char texture_trigger_frame_icon[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08,
0x08, 0x06, 0x00, 0x00, 0x00, 0xc4, 0x0f, 0xbe, 0x8b, 0x00, 0x00, 0x00,
0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x5c, 0x46, 0x00, 0x00, 0x5c,
0x46, 0x01, 0x14, 0x94, 0x43, 0x41, 0x00, 0x00, 0x00, 0x1b, 0x49, 0x44,
0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0x40, 0x02, 0xff, 0xa1, 0x00, 0x59,
0x8c, 0x89, 0x81, 0x00, 0xa0, 0x83, 0x02, 0xd2, 0x00, 0x59, 0xbe, 0x00,
0x00, 0x46, 0x35, 0x0f, 0xfb, 0x77, 0xd4, 0xf4, 0xcd, 0x00, 0x00, 0x00,
0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned int texture_trigger_frame_icon_len = 105;
static const unsigned char texture_target[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20,
0x08, 0x06, 0x00, 0x00, 0x00, 0x73, 0x7a, 0x7a, 0xf4, 0x00, 0x00, 0x00,
0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x5c, 0x46, 0x00, 0x00, 0x5c,
0x46, 0x01, 0x14, 0x94, 0x43, 0x41, 0x00, 0x00, 0x00, 0xb9, 0x49, 0x44,
0x41, 0x54, 0x58, 0xc3, 0xed, 0x56, 0x8b, 0x0a, 0x80, 0x30, 0x08, 0xec,
0x46, 0xff, 0xff, 0xcb, 0x8b, 0x81, 0x85, 0x94, 0x7b, 0xe8, 0x5a, 0x2e,
0x98, 0x10, 0x2c, 0x03, 0x3d, 0xf5, 0x76, 0xb9, 0x6d, 0x7f, 0xb6, 0x48,
0xd6, 0x13, 0x23, 0x78, 0x17, 0xb1, 0x00, 0xc0, 0x38, 0xfb, 0xeb, 0xc8,
0xe3, 0x00, 0x18, 0xdf, 0x81, 0x12, 0xe7, 0x2c, 0x7c, 0x34, 0x8d, 0x20,
0x55, 0xca, 0xab, 0xbd, 0xbf, 0x0f, 0x05, 0x50, 0x4a, 0xf4, 0xc9, 0x08,
0x66, 0x21, 0x61, 0xcc, 0x74, 0x00, 0xc3, 0x01, 0xd4, 0x94, 0x4f, 0x0b,
0x22, 0x18, 0x93, 0x83, 0x27, 0xa2, 0x33, 0x5a, 0x00, 0x36, 0x01, 0x48,
0x31, 0xce, 0xe7, 0x9e, 0x1c, 0x80, 0x58, 0x24, 0xf9, 0xd4, 0x20, 0x5e,
0x25, 0xa1, 0x04, 0x4c, 0x2a, 0xe6, 0xc1, 0x81, 0xde, 0x3f, 0x5a, 0x07,
0x60, 0xcc, 0x79, 0x0d, 0x79, 0x43, 0xce, 0xb6, 0x72, 0x0e, 0x48, 0xbc,
0xc8, 0xf9, 0xa4, 0x58, 0xdc, 0x76, 0xad, 0xa2, 0xa5, 0x80, 0xb9, 0xef,
0xd2, 0x24, 0x6b, 0xb7, 0x32, 0x68, 0xe6, 0x55, 0x92, 0x02, 0xf2, 0x45,
0xad, 0x16, 0xb8, 0x0b, 0x91, 0xbb, 0x14, 0xaf, 0xa5, 0xd4, 0x7d, 0x23,
0xda, 0x3b, 0x77, 0x42, 0x73, 0xe2, 0x69, 0x36, 0xa2, 0x45, 0xc2, 0x05,
0xc0, 0xdd, 0x0e, 0x27, 0x86, 0x84, 0x1b, 0x55, 0x64, 0x35, 0x3e, 0x00,
0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned int texture_target_len = 263;
static const unsigned char texture_pivot[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06,
0x08, 0x06, 0x00, 0x00, 0x00, 0xe0, 0xcc, 0xef, 0x48, 0x00, 0x00, 0x00,
0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x5c, 0x46, 0x00, 0x00, 0x5c,
0x46, 0x01, 0x14, 0x94, 0x43, 0x41, 0x00, 0x00, 0x00, 0x1e, 0x49, 0x44,
0x41, 0x54, 0x08, 0xd7, 0x63, 0x60, 0x80, 0x82, 0xff, 0x50, 0x00, 0xe3,
0x33, 0x31, 0xe0, 0x00, 0x8c, 0xc8, 0xaa, 0x90, 0x01, 0x4e, 0x1d, 0x0c,
0x24, 0xdb, 0x01, 0x00, 0xfa, 0x18, 0x13, 0xf4, 0x52, 0xd7, 0xb6, 0xe8,
0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned int texture_pivot_len = 108;
static const unsigned char texture_error[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0e,
0x08, 0x06, 0x00, 0x00, 0x00, 0x26, 0x2f, 0x9c, 0x8a, 0x00, 0x00, 0x00,
0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x5c, 0x46, 0x00, 0x00, 0x5c,
0x46, 0x01, 0x14, 0x94, 0x43, 0x41, 0x00, 0x00, 0x00, 0x5a, 0x49, 0x44,
0x41, 0x54, 0x28, 0xcf, 0xad, 0x53, 0x41, 0x0e, 0x00, 0x20, 0x08, 0x12,
0xff, 0xff, 0xe7, 0xf2, 0xe8, 0x4c, 0xd2, 0x65, 0xdc, 0x5a, 0xa0, 0x68,
0x04, 0x21, 0x58, 0x06, 0x7f, 0x86, 0x21, 0xe3, 0xa1, 0x12, 0x1e, 0x82,
0x50, 0x08, 0x4c, 0x1c, 0x89, 0xec, 0x0e, 0x91, 0xc0, 0xac, 0xb2, 0x91,
0x54, 0x1a, 0xb8, 0x8d, 0x85, 0xaa, 0x7b, 0x66, 0xdd, 0xf3, 0xb5, 0xdb,
0x99, 0x8d, 0xa6, 0x13, 0x31, 0x2d, 0xd0, 0x15, 0xa7, 0xaf, 0x50, 0x85,
0x27, 0xee, 0x4b, 0xbb, 0x81, 0x29, 0x1d, 0x8c, 0x83, 0xf4, 0x25, 0xca,
0x2f, 0x9f, 0x69, 0x03, 0x2f, 0x92, 0x4c, 0x14, 0x86, 0xa5, 0x1a, 0x1d,
0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned int texture_error_len = 168;
#define TEXTURE_COUNT (TEXTURE_ERROR + 1)
enum TextureType enum TextureType
{ {
TEXTURE_DUMMY,
TEXTURE_EYE_OPEN, TEXTURE_EYE_OPEN,
TEXTURE_EYE_CLOSED, TEXTURE_EYE_CLOSED,
TEXTURE_ANIMATION, TEXTURE_ANIMATION,
@@ -282,11 +433,21 @@ enum TextureType
TEXTURE_RECT_SHOW, TEXTURE_RECT_SHOW,
TEXTURE_RECT_HIDE, TEXTURE_RECT_HIDE,
TEXTURE_ARROW_UP, TEXTURE_ARROW_UP,
TEXTURE_ARROW_DOWN TEXTURE_ARROW_DOWN,
TEXTURE_FRAME,
TEXTURE_FRAME_ALTERNATE,
TEXTURE_PICKER,
TEXTURE_INTERPOLATED_FRAME_ICON,
TEXTURE_UNINTERPOLATED_FRAME_ICON,
TEXTURE_TRIGGER_FRAME_ICON,
TEXTURE_TARGET,
TEXTURE_PIVOT,
TEXTURE_ERROR
}; };
static const TextureData TEXTURE_DATA[TEXTURE_COUNT] = static const TextureData TEXTURE_DATA[TEXTURE_COUNT] =
{ {
{texture_dummy, texture_dummy_len},
{texture_eye_open, texture_eye_open_len}, {texture_eye_open, texture_eye_open_len},
{texture_eye_closed, texture_eye_closed_len}, {texture_eye_closed, texture_eye_closed_len},
{texture_animation, texture_animation_len}, {texture_animation, texture_animation_len},
@@ -300,6 +461,15 @@ static const TextureData TEXTURE_DATA[TEXTURE_COUNT] =
{texture_rect_hide, texture_rect_hide_len}, {texture_rect_hide, texture_rect_hide_len},
{texture_arrow_up, texture_arrow_up_len}, {texture_arrow_up, texture_arrow_up_len},
{texture_arrow_down, texture_arrow_down_len}, {texture_arrow_down, texture_arrow_down_len},
{texture_frame, texture_frame_len},
{texture_frame_alternate, texture_frame_alternate_len},
{texture_picker, texture_picker_len},
{texture_interpolated_frame_icon, texture_interpolated_frame_icon_len},
{texture_uninterpolated_frame_icon, texture_uninterpolated_frame_icon_len},
{texture_trigger_frame_icon, texture_trigger_frame_icon_len},
{texture_target, texture_target_len},
{texture_pivot, texture_pivot_len},
{texture_error, texture_error_len}
}; };
/* Shaders */ /* Shaders */
@@ -309,37 +479,61 @@ struct ShaderData
const char* fragment; const char* fragment;
}; };
#define SHADER_COUNT (SHADER + 1) #define SHADER_COUNT (SHADER_TEXTURE + 1)
enum ShaderType enum ShaderType
{ {
SHADER SHADER_LINE,
SHADER_TEXTURE
}; };
static const char SHADER_VERTEX[] = static const char SHADER_VERTEX[] =
"#version 330 core\n" \ "#version 330 core\n" \
"layout (location = 0)\n" \ "layout (location = 0) in vec2 i_position;\n" \
"in vec2 i_position;\n" \ "layout (location = 1) in vec2 i_uv;\n" \
"\n" \
"out vec2 i_uv_out;\n" \
"\n" \
"uniform mat4 u_transform;\n" \ "uniform mat4 u_transform;\n" \
"\n" \ "\n" \
"void main()\n" \ "void main()\n" \
"{\n" \ "{\n" \
" vec4 pos = vec4(i_position, 0.0, 1.0);\n" \ " i_uv_out = i_uv;\n" \
" gl_Position = u_transform * pos;\n" \ " gl_Position = u_transform * vec4(i_position, 0.0, 1.0);\n" \
"}\n"; "}\n";
static const char SHADER_FRAGMENT[] = "#version 330 core\n" \ static const char SHADER_TEXTURE_FRAGMENT[] =
"out vec4 FragColor;\n" \ "#version 330 core\n" \
"in vec2 i_uv_out;\n" \
"uniform sampler2D u_texture;\n" \
"uniform vec4 u_tint;\n" \
"uniform vec3 u_color_offset;\n" \
"out vec4 o_fragColor;\n" \
"void main()\n" \
"{\n" \
" vec4 texColor = texture(u_texture, i_uv_out);\n" \
" texColor *= u_tint;\n" \
" texColor.rgb += u_color_offset;\n" \
" o_fragColor = texColor;\n" \
"}\n";
static const char SHADER_FRAGMENT[] =
"#version 330 core\n" \
"out vec4 o_fragColor;\n" \
"uniform vec4 u_color;\n" \ "uniform vec4 u_color;\n" \
"\n" \ "\n" \
"void main()\n" \ "void main()\n" \
"{\n" \ "{\n" \
" FragColor = u_color;\n" \ " o_fragColor = u_color;\n" \
"}\n"; "}\n";
static const char SHADER_UNIFORM_COLOR[] = "u_color"; static const char SHADER_UNIFORM_COLOR[] = "u_color";
static const char SHADER_UNIFORM_TRANSFORM[] = "u_transform"; static const char SHADER_UNIFORM_TRANSFORM[] = "u_transform";
static const char SHADER_UNIFORM_TINT[] = "u_tint";
static const char SHADER_UNIFORM_COLOR_OFFSET[] = "u_color_offset";
static const char SHADER_UNIFORM_TEXTURE[] = "u_texture";
static const ShaderData SHADER_DATA[SHADER_COUNT] = static const ShaderData SHADER_DATA[SHADER_COUNT] =
{ {
{SHADER_VERTEX, SHADER_FRAGMENT} {SHADER_VERTEX, SHADER_FRAGMENT},
{SHADER_VERTEX, SHADER_TEXTURE_FRAGMENT}
}; };

View File

@@ -13,6 +13,7 @@
#define STRING_ERROR_TEXTURE_INIT "[ERROR] Could not initialize texture: %s\n" #define STRING_ERROR_TEXTURE_INIT "[ERROR] Could not initialize texture: %s\n"
#define STRING_ERROR_ANM2_READ "[ERROR] Could not read anm2 from file %s: %s\n" #define STRING_ERROR_ANM2_READ "[ERROR] Could not read anm2 from file %s: %s\n"
#define STRING_ERROR_ANM2_WRITE "[ERROR] Could not write anm2 to file %s: %s\n" #define STRING_ERROR_ANM2_WRITE "[ERROR] Could not write anm2 to file %s: %s\n"
#define STRING_ERROR_SETTINGS_INIT "[ERROR] Could not load settings file (%s). Should be created on program exit.\n"
#define STRING_INFO_INIT "[INFO] Initializing\n" #define STRING_INFO_INIT "[INFO] Initializing\n"
#define STRING_INFO_QUIT "[INFO] Exited\n" #define STRING_INFO_QUIT "[INFO] Exited\n"
@@ -25,6 +26,7 @@
#define STRING_INFO_TEXTURE_INIT "[INFO] Initialized texture: %s\n" #define STRING_INFO_TEXTURE_INIT "[INFO] Initialized texture: %s\n"
#define STRING_INFO_ANM2_WRITE "[INFO] Wrote anm2 to file: %s\n" #define STRING_INFO_ANM2_WRITE "[INFO] Wrote anm2 to file: %s\n"
#define STRING_INFO_ANM2_READ "[INFO] Read anm2 from file: %s\n" #define STRING_INFO_ANM2_READ "[INFO] Read anm2 from file: %s\n"
#define STRING_INFO_OPENGL "[INFO] OpenGL %s\n"
#define STRING_INFO_IMGUI_INIT "[INFO] Initialized Dear Imgui\n" #define STRING_INFO_IMGUI_INIT "[INFO] Initialized Dear Imgui\n"
#define STRING_INFO_IMGUI_FREE "[INFO] Freed Dear Imgui\n" #define STRING_INFO_IMGUI_FREE "[INFO] Freed Dear Imgui\n"
@@ -54,14 +56,6 @@
#define STRING_IMGUI_FILE_SAVE "Save" #define STRING_IMGUI_FILE_SAVE "Save"
#define STRING_IMGUI_FILE_SAVE_AS "Save As" #define STRING_IMGUI_FILE_SAVE_AS "Save As"
#define STRING_IMGUI_PROPERTIES "Properties"
#define STRING_IMGUI_PROPERTIES_FPS "FPS"
#define STRING_IMGUI_PROPERTIES_FPS_LABEL "##FPS"
#define STRING_IMGUI_PROPERTIES_CREATED_BY "Created by:"
#define STRING_IMGUI_PROPERTIES_CREATED_BY_LABEL "##Created By"
#define STRING_IMGUI_PROPERTIES_CREATED_ON "Created on: %s"
#define STRING_IMGUI_PROPERTIES_VERSION "Version: %i"
#define STRING_IMGUI_ANIMATIONS "Animations" #define STRING_IMGUI_ANIMATIONS "Animations"
#define STRING_IMGUI_ANIMATIONS_ANIMATION_LABEL "##Animation" #define STRING_IMGUI_ANIMATIONS_ANIMATION_LABEL "##Animation"
#define STRING_IMGUI_ANIMATIONS_ADD "Add" #define STRING_IMGUI_ANIMATIONS_ADD "Add"
@@ -95,13 +89,20 @@
#define STRING_IMGUI_FRAME_PROPERTIES_DURATION "Duration" #define STRING_IMGUI_FRAME_PROPERTIES_DURATION "Duration"
#define STRING_IMGUI_FRAME_PROPERTIES_TINT "Tint" #define STRING_IMGUI_FRAME_PROPERTIES_TINT "Tint"
#define STRING_IMGUI_FRAME_PROPERTIES_COLOR_OFFSET "Color Offset" #define STRING_IMGUI_FRAME_PROPERTIES_COLOR_OFFSET "Color Offset"
#define STRING_IMGUI_FRAME_PROPERTIES_EVENT "Event"
#define STRING_IMGUI_FRAME_PROPERTIES_AT_FRAME "At Frame"
#define STRING_IMGUI_FRAME_PROPERTIES_ROOT "-- Root --"
#define STRING_IMGUI_FRAME_PROPERTIES_LAYER "-- Layer -- "
#define STRING_IMGUI_FRAME_PROPERTIES_NULL "-- Null --"
#define STRING_IMGUI_FRAME_PROPERTIES_TRIGGER "-- Trigger --"
#define STRING_IMGUI_ANIMATION_PREVIEW "Animation Preview" #define STRING_IMGUI_ANIMATION_PREVIEW "Animation Preview"
#define STRING_IMGUI_ANIMATION_PREVIEW_LABEL "##Animation Preview" #define STRING_IMGUI_ANIMATION_PREVIEW_LABEL "##Animation Preview"
#define STRING_IMGUI_ANIMATION_PREVIEW_SETTINGS "##Animation Preview Settings" #define STRING_IMGUI_ANIMATION_PREVIEW_SETTINGS "##Animation Preview Settings"
#define STRING_IMGUI_ANIMATION_PREVIEW_GRID_SETTINGS "##Grid Settings" #define STRING_IMGUI_ANIMATION_PREVIEW_GRID_SETTINGS "##Grid Settings"
#define STRING_IMGUI_ANIMATION_PREVIEW_GRID "Grid" #define STRING_IMGUI_ANIMATION_PREVIEW_GRID "Grid"
#define STRING_IMGUI_ANIMATION_PREVIEW_GRID_SIZE "##Grid Size" #define STRING_IMGUI_ANIMATION_PREVIEW_GRID_SIZE "Size"
#define STRING_IMGUI_ANIMATION_PREVIEW_GRID_OFFSET "Offset"
#define STRING_IMGUI_ANIMATION_PREVIEW_GRID_COLOR "Color" #define STRING_IMGUI_ANIMATION_PREVIEW_GRID_COLOR "Color"
#define STRING_IMGUI_ANIMATION_PREVIEW_VIEW_SETTINGS "##View Settings" #define STRING_IMGUI_ANIMATION_PREVIEW_VIEW_SETTINGS "##View Settings"
#define STRING_IMGUI_ANIMATION_PREVIEW_ZOOM "Zoom" #define STRING_IMGUI_ANIMATION_PREVIEW_ZOOM "Zoom"
@@ -111,12 +112,15 @@
#define STRING_IMGUI_ANIMATION_PREVIEW_CENTER_VIEW "Center View" #define STRING_IMGUI_ANIMATION_PREVIEW_CENTER_VIEW "Center View"
#define STRING_IMGUI_ANIMATION_PREVIEW_AXIS "Axes" #define STRING_IMGUI_ANIMATION_PREVIEW_AXIS "Axes"
#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_SHOW_PIVOT "Show Pivot"
#define STRING_IMGUI_SPRITESHEET_EDITOR "Spritesheet Editor" #define STRING_IMGUI_SPRITESHEET_EDITOR "Spritesheet Editor"
#define STRING_IMGUI_TIMELINE "Timeline" #define STRING_IMGUI_TIMELINE "Timeline"
#define STRING_IMGUI_TIMELINE_ELEMENT_SHIFT_ABOVE "Shift Above" #define STRING_IMGUI_TIMELINE_ELEMENT_SHIFT_ABOVE "Shift Above"
#define STRING_IMGUI_TIMELINE_ELEMENT_SHIFT_BELOW "Shift Below" #define STRING_IMGUI_TIMELINE_ELEMENT_SHIFT_BELOW "Shift Below"
#define STRING_IMGUI_TIMELINE_ELEMENT_FRAMES "Element Frames"
#define STRING_IMGUI_TIMELINE_ROOT "Root" #define STRING_IMGUI_TIMELINE_ROOT "Root"
#define STRING_IMGUI_TIMELINE_ELEMENT_FORMAT "#%i %s" #define STRING_IMGUI_TIMELINE_ELEMENT_FORMAT "#%i %s"
#define STRING_IMGUI_TIMELINE_SPRITESHEET_FORMAT "#%i" #define STRING_IMGUI_TIMELINE_SPRITESHEET_FORMAT "#%i"
@@ -130,6 +134,9 @@
#define STRING_IMGUI_TIMELINE_PLAY "|> Play" #define STRING_IMGUI_TIMELINE_PLAY "|> Play"
#define STRING_IMGUI_TIMELINE_PAUSE "|| Pause" #define STRING_IMGUI_TIMELINE_PAUSE "|| Pause"
#define STRING_IMGUI_TIMELINE_FRAME_ADD "Add Frame" #define STRING_IMGUI_TIMELINE_FRAME_ADD "Add Frame"
#define STRING_IMGUI_TIMELINE_FRAMES "Frames"
#define STRING_IMGUI_TIMELINE_FRAME_LABEL "##Frame"
#define STRING_IMGUI_TIMELINE_TRIGGER_LABEL "##Trigger"
#define STRING_IMGUI_TIMELINE_FRAME_REMOVE "Remove Frame" #define STRING_IMGUI_TIMELINE_FRAME_REMOVE "Remove Frame"
#define STRING_IMGUI_TIMELINE_FIT_ANIMATION_LENGTH "= Fit Animation Length" #define STRING_IMGUI_TIMELINE_FIT_ANIMATION_LENGTH "= Fit Animation Length"
#define STRING_IMGUI_TIMELINE_ANIMATION LENGTH "Animation Length:" #define STRING_IMGUI_TIMELINE_ANIMATION LENGTH "Animation Length:"
@@ -141,11 +148,20 @@
#define STRING_IMGUI_TIMELINE_ANIMATION_LENGTH "Animation Length" #define STRING_IMGUI_TIMELINE_ANIMATION_LENGTH "Animation Length"
#define STRING_IMGUI_TIMELINE_ELEMENT_TIMELINE "Element Timeline" #define STRING_IMGUI_TIMELINE_ELEMENT_TIMELINE "Element Timeline"
#define STRING_IMGUI_TIMELINE_ELEMENTS "Elements" #define STRING_IMGUI_TIMELINE_ELEMENTS "Elements"
#define STRING_IMGUI_TIMELINE_ELEMENT_LIST "Element List"
#define STRING_IMGUI_TIMELINE_ELEMENT_ADD "Add Element" #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 "Element Add Menu"
#define STRING_IMGUI_TIMELINE_ELEMENT_ADD_MENU_LAYER "Add Layer..." #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_ADD_MENU_NULL "Add Null..."
#define STRING_IMGUI_TIMELINE_ELEMENT_REMOVE "Remove Element" #define STRING_IMGUI_TIMELINE_ELEMENT_REMOVE "Remove Element"
#define STRING_IMGUI_TIMELINE_LOOP "Loop"
#define STRING_IMGUI_TIMELINE_FPS "FPS"
#define STRING_IMGUI_TIMELINE_CREATED_BY "Author"
#define STRING_IMGUI_TIMELINE_CREATED_ON "Created on: %s"
#define STRING_IMGUI_TIMELINE_VERSION "Version: %i"
#define STRING_IMGUI_TIMELINE_VIEWER "Viewer"
#define STRING_IMGUI_TIMELINE_CHILD "Timeline"
#define STRING_IMGUI_TIMELINE_MAIN "Main"
#define STRING_IMGUI_TOOLTIP_ANIMATIONS_ADD "Add a new animation." #define STRING_IMGUI_TOOLTIP_ANIMATIONS_ADD "Add a new animation."
#define STRING_IMGUI_TOOLTIP_ANIMATIONS_DUPLICATE "Duplicates the selected animation." #define STRING_IMGUI_TOOLTIP_ANIMATIONS_DUPLICATE "Duplicates the selected animation."
@@ -157,16 +173,21 @@
#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."
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_CENTER_VIEW "Centers the preview's pan." #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 "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_GRID_COLOR "Changes the animation preview grid color."
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_GRID_OFFSET "Changes the grid's offset, in pixels."
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_GRID_SIZE "Changes the 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_SHOW_PIVOT "Toggle the pivots of layer animation elements being visible."
#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."
#define STRING_IMGUI_TOOLTIP_EVENTS_SELECT "Set the event for the trigger, or rename it." #define STRING_IMGUI_TOOLTIP_EVENTS_SELECT "Set the event for the trigger, or rename it."
#define STRING_IMGUI_TOOLTIP_FRAME_PROPERTIES_AT_FRAME "Sets the frame in which the trigger will activate."
#define STRING_IMGUI_TOOLTIP_FRAME_PROPERTIES_COLOR_OFFSET "Change the color offset of the frame." #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_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_CROP_SIZE "Change the crop size of the frame."
#define STRING_IMGUI_TOOLTIP_FRAME_PROPERTIES_DURATION "Change the duration of the frame." #define STRING_IMGUI_TOOLTIP_FRAME_PROPERTIES_DURATION "Change the duration of the frame."
#define STRING_IMGUI_TOOLTIP_FRAME_PROPERTIES_EVENT "Sets the event the trigger will use."
#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_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_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_POSITION "Change the position of the frame."
@@ -174,30 +195,33 @@
#define STRING_IMGUI_TOOLTIP_FRAME_PROPERTIES_SCALE "Change the scale 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_TINT "Change the tint of the frame."
#define STRING_IMGUI_TOOLTIP_FRAME_PROPERTIES_VISIBLE "Toggles the visibility 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_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_RELOAD "Reloads the selected spritesheet."
#define STRING_IMGUI_TOOLTIP_SPRITESHEETS_REMOVE "Removes 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_REPLACE "Replaces the selected spritesheet; opens up the file dialog."
#define STRING_IMGUI_TOOLTIP_SPRITESHEETS_SELECT "Select the spritesheet element." #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_ANIMATION_LENGTH "Changes the current animation's length."
#define STRING_IMGUI_TOOLTIP_TIMELINE_CREATED_BY "Change the author of the animation."
#define STRING_IMGUI_TOOLTIP_TIMELINE_CREATED_ON_NOW "Set the date of creation to the current system time."
#define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_ADD "Add a layer or null timeline element." #define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_ADD "Add a layer or null timeline 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_LAYER "This is a Layer element.\nThese are the main graphical animation elements.\nClick to select or rename."
#define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_NAME "Click to rename the element." #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_NULL "This is a Null element.\nThese are invisible elements where a game engine may have access to them for additional effects.\nClick to select or rename."
#define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_RECT "Toggle visibility for a rectangle around the null." #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_REMOVE "Remove a timeline element."
#define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_ROOT "This is the Root element." #define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_ROOT "This is the Root element.\nClick to select."
#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_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_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_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_ELEMENT_TRIGGERS "This is the animation's Triggers.\nTriggers are special activations; each is bound to an Event.\nClick to select."
#define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_VISIBLE "Toggle visibility for this element." #define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_VISIBLE "Toggle visibility for this element."
#define STRING_IMGUI_TOOLTIP_TIMELINE_FPS "Change the FPS of the animation."
#define STRING_IMGUI_TOOLTIP_TIMELINE_FRAME_ADD "Add a frame to the current selected 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_FRAME_REMOVE "Removes the selected frame from the current selected element."
#define STRING_IMGUI_TOOLTIP_TIMELINE_LOOP "Toggles the animation looping."
#define STRING_IMGUI_TOOLTIP_TIMELINE_PAUSE "Pauses the animation." #define STRING_IMGUI_TOOLTIP_TIMELINE_PAUSE "Pauses the animation."
#define STRING_IMGUI_TOOLTIP_TIMELINE_PLAY "Plays the animation." #define STRING_IMGUI_TOOLTIP_TIMELINE_PLAY "Plays the animation."
#define STRING_OPENGL_VERSION "#version 330" #define STRING_OPENGL_VERSION "#version 330"
#define PATH_SETTINGS "settings.ini"

View File

@@ -171,13 +171,13 @@ anm2_serialize(Anm2* self, const char* path)
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_Y_SCALE], frame.scale.y); /* XScale */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_Y_SCALE], frame.scale.y); /* XScale */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_DELAY], frame.delay); /* Delay */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_DELAY], frame.delay); /* Delay */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_VISIBLE], frame.isVisible); /* Visible */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_VISIBLE], frame.isVisible); /* Visible */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_RED_TINT], frame.tintRGBA.r); /* RedTint */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_RED_TINT], COLOR_FLOAT_TO_INT(frame.tintRGBA.r)); /* RedTint */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_GREEN_TINT], frame.tintRGBA.g); /* GreenTint */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_GREEN_TINT], COLOR_FLOAT_TO_INT(frame.tintRGBA.g)); /* GreenTint */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_BLUE_TINT], frame.tintRGBA.b); /* BlueTint */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_BLUE_TINT], COLOR_FLOAT_TO_INT(frame.tintRGBA.b)); /* BlueTint */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_ALPHA_TINT], frame.tintRGBA.a); /* AlphaTint */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_ALPHA_TINT], COLOR_FLOAT_TO_INT(frame.tintRGBA.a)); /* AlphaTint */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_RED_OFFSET], frame.offsetRGB.r); /* RedOffset */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_RED_OFFSET], COLOR_FLOAT_TO_INT(frame.offsetRGB.r)); /* RedOffset */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_GREEN_OFFSET], frame.offsetRGB.g); /* GreenOffset */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_GREEN_OFFSET], COLOR_FLOAT_TO_INT(frame.offsetRGB.g)); /* GreenOffset */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_BLUE_OFFSET], frame.offsetRGB.b); /* BlueOffset */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_BLUE_OFFSET], COLOR_FLOAT_TO_INT(frame.offsetRGB.b)); /* BlueOffset */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_ROTATION], frame.rotation); /* Rotation */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_ROTATION], frame.rotation); /* Rotation */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_INTERPOLATED], frame.isInterpolated); /* Interpolated */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_INTERPOLATED], frame.isInterpolated); /* Interpolated */
@@ -217,13 +217,13 @@ anm2_serialize(Anm2* self, const char* path)
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_Y_SCALE], frame.scale.y); /* XScale */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_Y_SCALE], frame.scale.y); /* XScale */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_DELAY], frame.delay); /* Delay */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_DELAY], frame.delay); /* Delay */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_VISIBLE], frame.isVisible); /* Visible */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_VISIBLE], frame.isVisible); /* Visible */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_RED_TINT], frame.tintRGBA.r); /* RedTint */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_RED_TINT], COLOR_FLOAT_TO_INT(frame.tintRGBA.r)); /* RedTint */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_GREEN_TINT], frame.tintRGBA.g); /* GreenTint */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_GREEN_TINT], COLOR_FLOAT_TO_INT(frame.tintRGBA.g)); /* GreenTint */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_BLUE_TINT], frame.tintRGBA.b); /* BlueTint */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_BLUE_TINT], COLOR_FLOAT_TO_INT(frame.tintRGBA.b)); /* BlueTint */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_ALPHA_TINT], frame.tintRGBA.a); /* AlphaTint */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_ALPHA_TINT], COLOR_FLOAT_TO_INT(frame.tintRGBA.a)); /* AlphaTint */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_RED_OFFSET], frame.offsetRGB.r); /* RedOffset */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_RED_OFFSET], COLOR_FLOAT_TO_INT(frame.offsetRGB.r)); /* RedOffset */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_GREEN_OFFSET], frame.offsetRGB.g); /* GreenOffset */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_GREEN_OFFSET], COLOR_FLOAT_TO_INT(frame.offsetRGB.g)); /* GreenOffset */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_BLUE_OFFSET], frame.offsetRGB.b); /* BlueOffset */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_BLUE_OFFSET], COLOR_FLOAT_TO_INT(frame.offsetRGB.b)); /* BlueOffset */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_ROTATION], frame.rotation); /* Rotation */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_ROTATION], frame.rotation); /* Rotation */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_INTERPOLATED], frame.isInterpolated); /* Interpolated */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_INTERPOLATED], frame.isInterpolated); /* Interpolated */
@@ -262,13 +262,13 @@ anm2_serialize(Anm2* self, const char* path)
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_Y_SCALE], frame.scale.y); /* XScale */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_Y_SCALE], frame.scale.y); /* XScale */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_DELAY], frame.delay); /* Delay */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_DELAY], frame.delay); /* Delay */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_VISIBLE], frame.isVisible); /* Visible */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_VISIBLE], frame.isVisible); /* Visible */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_RED_TINT], frame.tintRGBA.r); /* RedTint */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_RED_TINT], COLOR_FLOAT_TO_INT(frame.tintRGBA.r)); /* RedTint */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_GREEN_TINT], frame.tintRGBA.g); /* GreenTint */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_GREEN_TINT], COLOR_FLOAT_TO_INT(frame.tintRGBA.g)); /* GreenTint */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_BLUE_TINT], frame.tintRGBA.b); /* BlueTint */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_BLUE_TINT], COLOR_FLOAT_TO_INT(frame.tintRGBA.b)); /* BlueTint */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_ALPHA_TINT], frame.tintRGBA.a); /* AlphaTint */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_ALPHA_TINT], COLOR_FLOAT_TO_INT(frame.tintRGBA.a)); /* AlphaTint */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_RED_OFFSET], frame.offsetRGB.r); /* RedOffset */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_RED_OFFSET], COLOR_FLOAT_TO_INT(frame.offsetRGB.r)); /* RedOffset */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_GREEN_OFFSET], frame.offsetRGB.g); /* GreenOffset */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_GREEN_OFFSET], COLOR_FLOAT_TO_INT(frame.offsetRGB.g)); /* GreenOffset */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_BLUE_OFFSET], frame.offsetRGB.b); /* BlueOffset */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_BLUE_OFFSET], COLOR_FLOAT_TO_INT(frame.offsetRGB.b)); /* BlueOffset */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_ROTATION], frame.rotation); /* Rotation */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_ROTATION], frame.rotation); /* Rotation */
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_INTERPOLATED], frame.isInterpolated); /* Interpolated */ frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_INTERPOLATED], frame.isInterpolated); /* Interpolated */
@@ -341,6 +341,7 @@ anm2_deserialize(Anm2* self, Resources* resources, const char* path)
Anm2Layer tempLayer; Anm2Layer tempLayer;
Anm2Spritesheet tempSpritesheet; Anm2Spritesheet tempSpritesheet;
Anm2Event tempEvent; Anm2Event tempEvent;
char lastSpritesheetPath[PATH_MAX];
*self = Anm2{}; *self = Anm2{};
@@ -354,7 +355,8 @@ anm2_deserialize(Anm2* self, Resources* resources, const char* path)
resources_loaded_textures_free(resources); resources_loaded_textures_free(resources);
strncpy(self->path, path, PATH_MAX - 1); strncpy(self->path, path, PATH_MAX - 1);
working_directory_from_path_set(path);
root = document.FirstChildElement(ANM2_ELEMENT_STRINGS[ANM2_ELEMENT_ANIMATED_ACTOR]); root = document.FirstChildElement(ANM2_ELEMENT_STRINGS[ANM2_ELEMENT_ANIMATED_ACTOR]);
element = root; element = root;
@@ -472,8 +474,8 @@ anm2_deserialize(Anm2* self, Resources* resources, const char* path)
} }
break; break;
case ANM2_ATTRIBUTE_PATH: case ANM2_ATTRIBUTE_PATH:
strncpy(lastSpritesheet->path, attribute->Value(), PATH_MAX - 1); /* Make path lowercase */
anm2_spritesheet_texture_load(self, resources, attribute->Value(), id); strncpy(lastSpritesheetPath, attribute->Value(), PATH_MAX - 1);
break; break;
case ANM2_ATTRIBUTE_NAME: case ANM2_ATTRIBUTE_NAME:
switch (anm2Element) switch (anm2Element)
@@ -566,25 +568,25 @@ anm2_deserialize(Anm2* self, Resources* resources, const char* path)
} }
break; break;
case ANM2_ATTRIBUTE_RED_TINT: case ANM2_ATTRIBUTE_RED_TINT:
lastFrame->tintRGBA.r = atof(attribute->Value()); lastFrame->tintRGBA.r = COLOR_INT_TO_FLOAT(atoi(attribute->Value()));
break; break;
case ANM2_ATTRIBUTE_GREEN_TINT: case ANM2_ATTRIBUTE_GREEN_TINT:
lastFrame->tintRGBA.g = atof(attribute->Value()); lastFrame->tintRGBA.g = COLOR_INT_TO_FLOAT(atoi(attribute->Value()));
break; break;
case ANM2_ATTRIBUTE_BLUE_TINT: case ANM2_ATTRIBUTE_BLUE_TINT:
lastFrame->tintRGBA.b = atof(attribute->Value()); lastFrame->tintRGBA.b = COLOR_INT_TO_FLOAT(atoi(attribute->Value()));
break; break;
case ANM2_ATTRIBUTE_ALPHA_TINT: case ANM2_ATTRIBUTE_ALPHA_TINT:
lastFrame->tintRGBA.a = atof(attribute->Value()); lastFrame->tintRGBA.a = COLOR_INT_TO_FLOAT(atoi(attribute->Value()));
break; break;
case ANM2_ATTRIBUTE_RED_OFFSET: case ANM2_ATTRIBUTE_RED_OFFSET:
lastFrame->offsetRGB.r = atof(attribute->Value()); lastFrame->offsetRGB.r = COLOR_INT_TO_FLOAT(atoi(attribute->Value()));
break; break;
case ANM2_ATTRIBUTE_GREEN_OFFSET: case ANM2_ATTRIBUTE_GREEN_OFFSET:
lastFrame->offsetRGB.g = atof(attribute->Value()); lastFrame->offsetRGB.g = COLOR_INT_TO_FLOAT(atoi(attribute->Value()));
break; break;
case ANM2_ATTRIBUTE_BLUE_OFFSET: case ANM2_ATTRIBUTE_BLUE_OFFSET:
lastFrame->offsetRGB.b = atof(attribute->Value()); lastFrame->offsetRGB.b = COLOR_INT_TO_FLOAT(atoi(attribute->Value()));
break; break;
case ANM2_ATTRIBUTE_ROTATION: case ANM2_ATTRIBUTE_ROTATION:
lastFrame->rotation = atof(attribute->Value()); lastFrame->rotation = atof(attribute->Value());
@@ -615,6 +617,13 @@ anm2_deserialize(Anm2* self, Resources* resources, const char* path)
attribute = attribute->Next(); attribute = attribute->Next();
} }
/* Load spritesheet textures */
if (anm2Element == ANM2_ELEMENT_SPRITESHEET)
{
strncpy(lastSpritesheet->path, lastSpritesheetPath, PATH_MAX);
anm2_spritesheet_texture_load(self, resources, lastSpritesheetPath , id);
}
/* Iterate through children */ /* Iterate through children */
child = element->FirstChildElement(); child = element->FirstChildElement();
@@ -642,8 +651,6 @@ anm2_deserialize(Anm2* self, Resources* resources, const char* path)
} }
} }
working_directory_from_path_set(path);
printf(STRING_INFO_ANM2_READ, path); printf(STRING_INFO_ANM2_READ, path);
return true; return true;
@@ -702,12 +709,19 @@ 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] = Anm2LayerAnimation{};
}
/* match nulls */ /* match nulls */
for (auto & [nullID, null] : self->nulls) for (auto & [nullID, null] : self->nulls)
animation.nullAnimations[nullID] = Anm2NullAnimation{}; {
animation.nullAnimations[nullID] = Anm2NullAnimation{};
}
/* add a root frame */
animation.rootAnimation.frames.push_back(Anm2Frame{});
self->animations[id] = animation; self->animations[id] = animation;
return id; return id;
@@ -732,10 +746,99 @@ anm2_spritesheet_texture_load(Anm2* self, Resources* resources, const char* path
{ {
Texture texture; Texture texture;
/* free texture if it exists */ /* free texture if it exists, and if it's not texture error */
if (resources->loadedTextures.find(id) != resources->loadedTextures.end()) if
(
resources->loadedTextures.find(id) != resources->loadedTextures.end() &&
resources->loadedTextures[id].handle != resources->textures[TEXTURE_ERROR].handle
)
texture_free(&resources->loadedTextures[id]); texture_free(&resources->loadedTextures[id]);
texture_from_path_init(&texture, path); if (texture_from_path_init(&texture, path))
resources->loadedTextures[id] = texture; resources->loadedTextures[id] = texture;
else
{
resources->loadedTextures[id] = resources->textures[TEXTURE_ERROR];
resources->loadedTextures[id].isInvalid = true;
}
}
/* Creates/fetches a frame from a given time. */
/* Returns true/false if frame will be valid or not. */
bool
anm2_frame_from_time(Anm2* self, Anm2Animation* animation, Anm2Frame* frame, Anm2AnimationType type, s32 id, f32 time)
{
/* Out of range */
if (time < 0 || time > animation->frameNum)
return false;
Anm2RootAnimation* rootAnimation;
Anm2LayerAnimation* layerAnimation;
Anm2NullAnimation* nullAnimation;
Anm2Frame* baseFrame = NULL;
Anm2Frame* nextFrame = NULL;
std::vector<Anm2Frame>* frames = NULL;
f32 delayCurrent = 0;
f32 delayNext = 0;
bool isBaseFrame = 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++)
{
Anm2Frame* frame = &(*frames)[i];
delayNext += frame->delay;
if (time >= delayCurrent && time < delayNext)
{
baseFrame = frame;
if (i + 1 < (s32)frames->size())
nextFrame = &(*frames)[i + 1];
else
nextFrame = NULL;
isBaseFrame = true;
break;
}
delayCurrent += frame->delay;
}
/* No valid frame found */
if (!isBaseFrame)
return false;
*frame = *baseFrame;
/* interpolate only if there's a frame following */
if (frame->isInterpolated && nextFrame)
{
f32 interpolationTime = (time - delayCurrent) / (delayNext - delayCurrent);
frame->rotation = glm::mix(baseFrame->rotation, nextFrame->rotation, interpolationTime);;
frame->position = glm::mix(baseFrame->position, nextFrame->position, interpolationTime);;
frame->scale = glm::mix(baseFrame->scale, nextFrame->scale, interpolationTime);;
frame->offsetRGB = glm::mix(baseFrame->offsetRGB, nextFrame->offsetRGB, interpolationTime);;
frame->tintRGBA = glm::mix(baseFrame->tintRGBA, nextFrame->tintRGBA, interpolationTime);;
}
return true;
} }

View File

@@ -11,8 +11,9 @@
#define ANM2_PATH_FORMATTED_MAX PATH_MAX + 0xFF #define ANM2_PATH_FORMATTED_MAX PATH_MAX + 0xFF
#define ANM2_BUFFER_MAX 0xFFFFF #define ANM2_BUFFER_MAX 0xFFFFF
#define ANM2_FPS_MIN 0 #define ANM2_FPS_MIN 0
#define ANM2_FPS_DEFAULT 30 #define ANM2_FPS_MAX 120
#define ANM2_FPS_MAX 60 #define ANM2_FRAME_NUM_MIN 1
#define ANM2_FRAME_NUM_MAX 1000000
/* Elements */ /* Elements */
#define ANM2_ELEMENT_LIST \ #define ANM2_ELEMENT_LIST \
@@ -114,7 +115,7 @@ enum Anm2AnimationType
ANM2_ROOT_ANIMATION, ANM2_ROOT_ANIMATION,
ANM2_LAYER_ANIMATION, ANM2_LAYER_ANIMATION,
ANM2_NULL_ANIMATION, ANM2_NULL_ANIMATION,
ANM2_TRIGGERS ANM2_TRIGGER
}; };
struct Anm2Spritesheet struct Anm2Spritesheet
@@ -154,10 +155,10 @@ struct Anm2Frame
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};
vec2 size = {1.0f, 1.0f}; vec2 size = {0.0f, 0.0f};
vec2 scale = {1.0f, 1.0f}; vec2 scale = {100.0f, 100.0f};
ivec3 offsetRGB = {0, 0, 0}; vec3 offsetRGB = {0.0f, 0.0f, 0.0f};
ivec4 tintRGBA = {255, 255, 255, 255}; vec4 tintRGBA = {1.0f, 1.0f, 1.0f, 1.0f};
}; };
struct Anm2LayerAnimation struct Anm2LayerAnimation
@@ -186,7 +187,7 @@ struct Anm2Triggers
struct Anm2Animation struct Anm2Animation
{ {
s32 frameNum = 0; 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; Anm2RootAnimation rootAnimation;
@@ -198,7 +199,7 @@ struct Anm2Animation
struct Anm2 struct Anm2
{ {
char path[PATH_MAX] = STRING_EMPTY; char path[PATH_MAX] = STRING_EMPTY;
s32 fps = ANM2_FPS_DEFAULT; s32 fps = 30;
s32 version = 0; s32 version = 0;
char createdBy[ANM2_STRING_MAX] = STRING_ANM2_CREATED_BY_DEFAULT; char createdBy[ANM2_STRING_MAX] = STRING_ANM2_CREATED_BY_DEFAULT;
char createdOn[ANM2_STRING_MAX] = STRING_EMPTY; char createdOn[ANM2_STRING_MAX] = STRING_EMPTY;
@@ -220,4 +221,5 @@ void anm2_new(Anm2* self);
void anm2_created_on_set(Anm2* self); 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);

View File

@@ -16,14 +16,14 @@ _dialog_callback(void* userdata, const char* const* filelist, s32 filter)
} }
else else
self->isSelected = false; self->isSelected = false;
} }
void void
dialog_init(Dialog* self, Anm2* anm2, Resources* resources) dialog_init(Dialog* self, Anm2* anm2, Resources* resources, SDL_Window* window)
{ {
self->anm2 = anm2; self->anm2 = anm2;
self->resources = resources; self->resources = resources;
self->window = window;
} }
/* Opens file dialog for user to pick anm2 files */ /* Opens file dialog for user to pick anm2 files */
@@ -76,11 +76,13 @@ dialog_tick(Dialog* self)
switch (self->type) switch (self->type)
{ {
case DIALOG_ANM2_OPEN: case DIALOG_ANM2_OPEN:
anm2_deserialize(self->anm2, self->resources, relativePath);
resources_loaded_textures_free(self->resources); resources_loaded_textures_free(self->resources);
anm2_deserialize(self->anm2, self->resources, self->path);
window_title_from_anm2_set(self->window, self->anm2);
break; break;
case DIALOG_ANM2_SAVE: case DIALOG_ANM2_SAVE:
anm2_serialize(self->anm2, relativePath); anm2_serialize(self->anm2, relativePath);
window_title_from_anm2_set(self->window, self->anm2);
break; break;
case DIALOG_PNG_OPEN: case DIALOG_PNG_OPEN:
id = map_next_id_get(self->resources->loadedTextures); id = map_next_id_get(self->resources->loadedTextures);

View File

@@ -2,6 +2,7 @@
#include "anm2.h" #include "anm2.h"
#include "resources.h" #include "resources.h"
#include "window.h"
static const SDL_DialogFileFilter DIALOG_FILE_FILTER_ANM2[] = static const SDL_DialogFileFilter DIALOG_FILE_FILTER_ANM2[] =
{ {
@@ -26,13 +27,14 @@ struct Dialog
{ {
Anm2* anm2 = NULL; Anm2* anm2 = NULL;
Resources* resources = NULL; Resources* resources = NULL;
SDL_Window* window = NULL;
s32 replaceID = -1; s32 replaceID = -1;
enum DialogType type = DIALOG_NONE; enum DialogType type = DIALOG_NONE;
char path[PATH_MAX] = ""; char path[PATH_MAX] = "";
bool isSelected = false; bool isSelected = false;
}; };
void dialog_init(Dialog* self, Anm2* anm2, Resources* resources); void dialog_init(Dialog* self, Anm2* anm2, 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);

File diff suppressed because it is too large Load Diff

View File

@@ -5,6 +5,7 @@
#include "preview.h" #include "preview.h"
#include "window.h" #include "window.h"
#include "input.h" #include "input.h"
#include "settings.h"
#define IMGUI_IMPL_OPENGL_LOADER_CUSTOM #define IMGUI_IMPL_OPENGL_LOADER_CUSTOM
#define IMGUI_ENABLE_DOCKING #define IMGUI_ENABLE_DOCKING
@@ -15,34 +16,50 @@
#define IMGUI_DRAG_SPEED 1.0 #define IMGUI_DRAG_SPEED 1.0
#define IMGUI_TASKBAR_HEIGHT 32 #define IMGUI_TASKBAR_HEIGHT 32
#define IMGUI_TIMELINE_OFFSET_Y 32 #define IMGUI_TIMELINE_OFFSET_Y 24
#define IMGUI_TIMELINE_ANIMATION_LENGTH_WIDTH 200 #define IMGUI_TIMELINE_ANIMATION_LENGTH_WIDTH 200
#define IMGUI_TIMELINE_FPS_WIDTH 100
#define IMGUI_TIMELINE_CREATED_BY_WIDTH 150
#define IMGUI_TIMELINE_FRAME_INDICES_MULTIPLE 5
#define IMGUI_TIMELINE_FRAME_INDICES_STRING_MAX 16
#define IMGUI_PICKER_LINE_SIZE 1.0f
#define IMGUI_FRAME_BORDER 2.0f
#define IMGUI_PICKER_LINE_COLOR IM_COL32(255, 255, 255, 255)
static const vec2 IMGUI_TASKBAR_MARGINS = {8, 4}; static const vec2 IMGUI_TASKBAR_MARGINS = {8, 4};
static const ImVec2 IMGUI_ANIMATION_PREVIEW_SETTINGS_SIZE = {1280, 80}; static const ImVec2 IMGUI_ANIMATION_PREVIEW_SETTINGS_SIZE = {1280, 105};
static const ImVec2 IMGUI_ANIMATION_PREVIEW_SETTINGS_CHILD_SIZE = {150, 64}; static const ImVec2 IMGUI_ANIMATION_PREVIEW_SETTINGS_CHILD_SIZE = {175, 85};
static const ImVec2 IMGUI_ANIMATION_PREVIEW_POSITION = {8, 110}; 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_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_LIST_SIZE = {300, 0};
static const ImVec2 IMGUI_TIMELINE_FRAMES_SIZE = {0, 0};
static const ImVec2 IMGUI_TIMELINE_ELEMENT_FRAMES_SIZE = {0, 0};
static const ImVec2 IMGUI_TIMELINE_FRAME_SIZE = {16, 40};
static const ImVec2 IMGUI_TIMELINE_VIEWER_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_ELEMENT_SIZE = {300, 40}; 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_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_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_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_DUMMY_SIZE = {20, 16};
static const ImVec2 IMGUI_ICON_BUTTON_SIZE = {24, 24}; 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_DUMMY_SIZE = {1, 1}; static const ImVec2 IMGUI_DUMMY_SIZE = {1, 1};
static const ImVec4 IMGUI_FRAME_BORDER_COLOR = {1.0f, 1.0f, 1.0f, 0.5f};
static const ImVec4 IMGUI_FRAME_OVERLAY_COLOR = {0.0f, 0.0f, 0.0f, 0.25f};
static const ImVec4 IMGUI_FRAME_INDICES_OVERLAY_COLOR = {0.113, 0.184, 0.286, 1.0f};
static const ImVec4 IMGUI_FRAME_INDICES_COLOR = {0.113, 0.184, 0.286, 0.5f};
#define IMGUI_TIMELINE_SHIFT_ARROWS_WIDTH (IMGUI_TIMELINE_SHIFT_ARROWS_SIZE.x * 1.35) #define IMGUI_TIMELINE_SHIFT_ARROWS_WIDTH (IMGUI_TIMELINE_SHIFT_ARROWS_SIZE.x * 1.35)
struct Imgui struct Imgui
@@ -54,6 +71,15 @@ struct Imgui
Preview* preview = NULL; Preview* preview = NULL;
SDL_Window* window = NULL; SDL_Window* window = NULL;
SDL_GLContext* glContext = NULL; SDL_GLContext* glContext = NULL;
Settings* settings = NULL;
s32 animationID = -1;
s32 timelineElementID = -1;
s32 eventID = -1;
s32 spritesheetID = -1;
s32 timelineElementIndex = -1;
Anm2AnimationType animationType = ANM2_NONE;
void* frameVector = NULL;
s32 frameIndex = -1;
}; };
void imgui_init void imgui_init
@@ -64,6 +90,7 @@ void imgui_init
Input* input, Input* input,
Anm2* anm2, Anm2* anm2,
Preview* preview, Preview* preview,
Settings* settings,
SDL_Window* window, SDL_Window* window,
SDL_GLContext* glContext SDL_GLContext* glContext
); );

View File

@@ -9,11 +9,24 @@ enum MouseType
MOUSE_RIGHT MOUSE_RIGHT
}; };
#define KEY_COUNT (KEY_DELETE + 1)
enum KeyType
{
KEY_DELETE
};
#define INPUT_COUNT (INPUT_MOUSE_CLICK + 1)
enum InputType enum InputType
{ {
INPUT_MOUSE_CLICK INPUT_MOUSE_CLICK
}; };
struct Keyboard
{
bool current[MOUSE_COUNT];
bool previous[MOUSE_COUNT];
};
struct Mouse struct Mouse
{ {
bool current[MOUSE_COUNT]; bool current[MOUSE_COUNT];
@@ -26,6 +39,7 @@ struct Mouse
struct Input struct Input
{ {
Keyboard keyboard;
Mouse mouse; Mouse mouse;
}; };

View File

@@ -11,7 +11,7 @@ _preview_axis_set(Preview* self)
glBufferData(GL_ARRAY_BUFFER, sizeof(PREVIEW_AXIS_VERTICES), PREVIEW_AXIS_VERTICES, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(PREVIEW_AXIS_VERTICES), PREVIEW_AXIS_VERTICES, GL_STATIC_DRAW);
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(f32), (void*)0);
glBindVertexArray(0); glBindVertexArray(0);
} }
@@ -21,13 +21,13 @@ _preview_grid_set(Preview* self)
{ {
std::vector<f32> vertices; std::vector<f32> vertices;
s32 verticalLineCount = PREVIEW_SIZE.x / self->gridSize.x; s32 verticalLineCount = PREVIEW_SIZE.x / MIN(self->settings->gridSizeX, PREVIEW_GRID_MIN);
s32 horizontalLineCount = PREVIEW_SIZE.y / self->gridSize.y; s32 horizontalLineCount = PREVIEW_SIZE.y / MIN(self->settings->gridSizeY, PREVIEW_GRID_MIN);
/* Vertical */ /* Vertical */
for (s32 i = 0; i <= verticalLineCount; i++) for (s32 i = 0; i <= verticalLineCount; i++)
{ {
s32 x = i * self->gridSize.x; s32 x = i * self->settings->gridSizeX - self->settings->gridOffsetX;
f32 normX = (2.0f * x) / PREVIEW_SIZE.x - 1.0f; f32 normX = (2.0f * x) / PREVIEW_SIZE.x - 1.0f;
vertices.push_back(normX); vertices.push_back(normX);
@@ -39,7 +39,7 @@ _preview_grid_set(Preview* self)
/* Horizontal */ /* Horizontal */
for (s32 i = 0; i <= horizontalLineCount; i++) for (s32 i = 0; i <= horizontalLineCount; i++)
{ {
s32 y = i * self->gridSize.y; s32 y = i * self->settings->gridSizeY - self->settings->gridOffsetY;
f32 normY = (2.0f * y) / PREVIEW_SIZE.y - 1.0f; f32 normY = (2.0f * y) / PREVIEW_SIZE.y - 1.0f;
vertices.push_back(-1.0f); vertices.push_back(-1.0f);
@@ -52,17 +52,19 @@ _preview_grid_set(Preview* self)
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(float), 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);
} }
void void
preview_init(Preview* self, Resources* resources, Input* input) preview_init(Preview* self, Anm2* anm2, Resources* resources, Input* input, Settings* settings)
{ {
self->anm2 = anm2;
self->resources = resources; self->resources = resources;
self->input = input; self->input = input;
self->settings = settings;
glGenFramebuffers(1, &self->fbo); glGenFramebuffers(1, &self->fbo);
@@ -89,6 +91,28 @@ preview_init(Preview* self, Resources* resources, Input* input)
glGenVertexArrays(1, &self->gridVAO); glGenVertexArrays(1, &self->gridVAO);
glGenBuffers(1, &self->gridVBO); glGenBuffers(1, &self->gridVBO);
glGenVertexArrays(1, &self->textureVAO);
glGenBuffers(1, &self->textureVBO);
glGenBuffers(1, &self->textureEBO);
glBindVertexArray(self->textureVAO);
glBindBuffer(GL_ARRAY_BUFFER, self->textureVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(f32) * 4 * 4, NULL, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self->textureEBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(PREVIEW_TEXTURE_INDICES), PREVIEW_TEXTURE_INDICES, GL_STATIC_DRAW);
/* Position */
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(f32), (void*)0);
/* UV */
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(f32), (void*)(2 * sizeof(f32)));
glBindVertexArray(0);
_preview_axis_set(self); _preview_axis_set(self);
_preview_grid_set(self); _preview_grid_set(self);
} }
@@ -96,52 +120,74 @@ preview_init(Preview* self, Resources* resources, Input* input)
void void
preview_tick(Preview* self) preview_tick(Preview* self)
{ {
self->zoom = CLAMP(self->zoom, PREVIEW_ZOOM_MIN, PREVIEW_ZOOM_MAX); self->settings->zoom = CLAMP(self->settings->zoom, PREVIEW_ZOOM_MIN, PREVIEW_ZOOM_MAX);
self->oldGridSize = self->gridSize; self->oldGridSize = glm::vec2(self->settings->gridSizeX, self->settings->gridSizeY);
self->oldGridOffset = glm::vec2(self->settings->gridOffsetX, self->settings->gridOffsetY);
if (self->animationID > -1)
{
Anm2Animation* animation = &self->anm2->animations[self->animationID];
if (self->isPlaying)
{
self->time += (f32)self->anm2->fps / TICK_RATE;
if (self->time >= (f32)animation->frameNum - 1)
self->time = 0.0f;
}
else
self->time = CLAMP(self->time, 0.0f, (f32)animation->frameNum);
}
} }
void void
preview_draw(Preview* self) preview_draw(Preview* self)
{ {
GLuint shader = self->resources->shaders[SHADER]; GLuint shaderLine = self->resources->shaders[SHADER_LINE];
float zoomFactor = self->zoom / 100.0f; GLuint shaderTexture = self->resources->shaders[SHADER_TEXTURE];
f32 zoomFactor = self->settings->zoom / 100.0f;
/* Convert pan to pixels */ /* Convert pan to pixels */
glm::vec2 ndcPan = glm::vec2( glm::vec2 ndcPan = glm::vec2(
self->pan.x / (PREVIEW_SIZE.x / 2.0f), self->settings->panX / (PREVIEW_SIZE.x / 2.0f),
-self->pan.y / (PREVIEW_SIZE.y / 2.0f) -self->settings->panY / (PREVIEW_SIZE.y / 2.0f)
); );
/* Transformation matrix */ /* Transformation matrix */
glm::mat4 transform = glm::translate(glm::mat4(1.0f), glm::vec3(ndcPan, 0.0f)); glm::mat4 previewTransform = glm::translate(glm::mat4(1.0f), glm::vec3(ndcPan, 0.0f));
transform = glm::scale(transform, glm::vec3(zoomFactor, zoomFactor, 1.0f)); previewTransform = glm::scale(previewTransform, glm::vec3(zoomFactor, zoomFactor, 1.0f));
glBindFramebuffer(GL_FRAMEBUFFER, self->fbo); glBindFramebuffer(GL_FRAMEBUFFER, self->fbo);
glViewport(0, 0, PREVIEW_SIZE.x, PREVIEW_SIZE.y); glViewport(0, 0, PREVIEW_SIZE.x, PREVIEW_SIZE.y);
glClearColor glClearColor
( (
self->backgroundColor.r, self->settings->backgroundColorR,
self->backgroundColor.g, self->settings->backgroundColorG,
self->backgroundColor.b, self->settings->backgroundColorB,
self->backgroundColor.a self->settings->backgroundColorA
); );
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shader); glUseProgram(shaderLine);
glUniformMatrix4fv(glGetUniformLocation(shader, SHADER_UNIFORM_TRANSFORM), 1, GL_FALSE, (f32*)value_ptr(transform)); glUniformMatrix4fv(glGetUniformLocation(shaderLine, SHADER_UNIFORM_TRANSFORM), 1, GL_FALSE, (f32*)value_ptr(previewTransform));
if (self->isGrid) if (self->settings->isGrid)
{ {
if (self->gridSize != self->oldGridSize) if
(
(ivec2(self->settings->gridSizeX, self->settings->gridSizeY) != self->oldGridSize) ||
(ivec2(self->settings->gridOffsetX, self->settings->gridOffsetY) != self->oldGridOffset)
)
_preview_grid_set(self); _preview_grid_set(self);
glBindVertexArray(self->gridVAO); glBindVertexArray(self->gridVAO);
glUniform4f glUniform4f
( (
glGetUniformLocation(shader, SHADER_UNIFORM_COLOR), glGetUniformLocation(shaderLine, SHADER_UNIFORM_COLOR),
self->gridColor.r, self->gridColor.g, self->gridColor.b, self->gridColor.a self->settings->gridColorR, self->settings->gridColorG, self->settings->gridColorB, self->settings->gridColorA
); );
glDrawArrays(GL_LINES, 0, self->gridVertexCount); glDrawArrays(GL_LINES, 0, self->gridVertexCount);
@@ -149,31 +195,264 @@ preview_draw(Preview* self)
glBindVertexArray(0); glBindVertexArray(0);
} }
if (self->isAxis) if (self->settings->isAxis)
{ {
glBindVertexArray(self->axisVAO); glBindVertexArray(self->axisVAO);
/* Axes */ /* Axes */
glUniform4f glUniform4f
( (
glGetUniformLocation(shader, SHADER_UNIFORM_COLOR), glGetUniformLocation(shaderLine, SHADER_UNIFORM_COLOR),
self->axisColor.r, self->axisColor.g, self->axisColor.b, self->axisColor.a self->settings->axisColorR, self->settings->axisColorG, self->settings->axisColorB, self->settings->axisColorA
); );
glDrawArrays(GL_LINES, 0, 2); glDrawArrays(GL_LINES, 0, 2);
glUniform4f glUniform4f
( (
glGetUniformLocation(shader, SHADER_UNIFORM_COLOR), glGetUniformLocation(shaderLine, SHADER_UNIFORM_COLOR),
self->axisColor.r, self->axisColor.g, self->axisColor.b, self->axisColor.a self->settings->axisColorR, self->settings->axisColorG, self->settings->axisColorB, self->settings->axisColorA
); );
glDrawArrays(GL_LINES, 2, 2); glDrawArrays(GL_LINES, 2, 2);
glBindVertexArray(0); glBindVertexArray(0);
} }
glUseProgram(0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glUseProgram(0);
glUseProgram(shaderTexture);
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) */
for (auto & [id, layerAnimation] : animation->layerAnimations)
{
Anm2Layer* layer = &self->anm2->layers[id];
Anm2Frame frame;
Texture* texture = &self->resources->loadedTextures[layer->spritesheetID];
if (texture->isInvalid)
continue;
if (!layerAnimation.isVisible || layerAnimation.frames.size() <= 0)
continue;
if (!anm2_frame_from_time(self->anm2, animation, &frame, ANM2_LAYER_ANIMATION, id, self->time))
continue;
if (!frame.isVisible)
continue;
glm::mat4 layerTransform = previewTransform;
glm::vec2 previewSize = glm::vec2(PREVIEW_SIZE);
glm::vec2 scale = self->settings->isRootTransform ?
(frame.scale / 100.0f) * (rootFrame.scale / 100.0f) :
(frame.scale / 100.0f);
glm::vec2 position = self->settings->isRootTransform ?
(frame.position + rootFrame.position) :
frame.position;
glm::vec2 scaledSize = frame.size * scale;
glm::vec2 scaledPivot = frame.pivot * scale;
glm::vec2 ndcPos = position / (previewSize / 2.0f);
glm::vec2 ndcPivotOffset = scaledPivot / (previewSize * 0.5f);
glm::vec2 ndcScale = scaledSize / (previewSize * 0.5f);
layerTransform = glm::translate(layerTransform, glm::vec3(ndcPos - ndcPivotOffset, 0.0f));
layerTransform = glm::translate(layerTransform, glm::vec3(ndcPivotOffset, 0.0f));
layerTransform = glm::rotate(layerTransform, glm::radians(frame.rotation), glm::vec3(0, 0, 1));
layerTransform = glm::translate(layerTransform, glm::vec3(-ndcPivotOffset, 0.0f));
layerTransform = glm::scale(layerTransform, glm::vec3(ndcScale, 1.0f));
glm::vec2 uvMin = frame.crop / glm::vec2(texture->size);
glm::vec2 uvMax = (frame.crop + frame.size) / glm::vec2(texture->size);
f32 vertices[] = {
0, 0, uvMin.x, uvMin.y,
1, 0, uvMax.x, uvMin.y,
1, 1, uvMax.x, uvMax.y,
0, 1, uvMin.x, uvMax.y
};
glBindVertexArray(self->textureVAO);
glBindBuffer(GL_ARRAY_BUFFER, self->textureVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture->handle);
glUniform1i(glGetUniformLocation(shaderTexture, SHADER_UNIFORM_TEXTURE), 0);
glUniform4fv(glGetUniformLocation(shaderTexture, SHADER_UNIFORM_TINT), 1, (f32*)value_ptr(frame.tintRGBA));
glUniform3fv(glGetUniformLocation(shaderTexture, SHADER_UNIFORM_COLOR_OFFSET), 1, (f32*)value_ptr(frame.offsetRGB));
glUniformMatrix4fv(glGetUniformLocation(shaderTexture, SHADER_UNIFORM_TRANSFORM), 1, GL_FALSE, value_ptr(layerTransform));
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindTexture(GL_TEXTURE_2D, 0);
}
/* Root */
if
(isRootFrame && animation->rootAnimation.isVisible && rootFrame.isVisible)
{
glm::mat4 rootTransform = previewTransform;
glm::vec2 previewSize = {(f32)PREVIEW_SIZE.x, (f32)PREVIEW_SIZE.y};
glm::vec2 ndcPos = (rootFrame.position - (PREVIEW_TARGET_SIZE / 2.0f)) / (previewSize / 2.0f);
glm::vec2 ndcScale = PREVIEW_TARGET_SIZE / (previewSize * 0.5f);
rootTransform = glm::translate(rootTransform, glm::vec3(ndcPos, 0.0f));
rootTransform = glm::scale(rootTransform, glm::vec3(ndcScale, 1.0f));
f32 vertices[] =
{
0, 0, 0.0f, 0.0f,
1, 0, 1.0f, 0.0f,
1, 1, 1.0f, 1.0f,
0, 1, 0.0f, 1.0f
};
glBindVertexArray(self->textureVAO);
glBindBuffer(GL_ARRAY_BUFFER, self->textureVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, self->resources->textures[TEXTURE_TARGET].handle);
glUniform1i(glGetUniformLocation(shaderTexture, SHADER_UNIFORM_TEXTURE), 0);
glUniform4fv(glGetUniformLocation(shaderTexture, SHADER_UNIFORM_TINT), 1, value_ptr(PREVIEW_ROOT_TINT));
glUniform3fv(glGetUniformLocation(shaderTexture, SHADER_UNIFORM_COLOR_OFFSET), 1, value_ptr(PREVIEW_ROOT_COLOR_OFFSET));
glUniformMatrix4fv(glGetUniformLocation(shaderTexture, SHADER_UNIFORM_TRANSFORM), 1, GL_FALSE, value_ptr(rootTransform));
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindTexture(GL_TEXTURE_2D, 0);
}
/* Pivots */
if (self->settings->isShowPivot)
{
for (auto it = animation->layerAnimations.rbegin(); it != animation->layerAnimations.rend(); it++)
{
s32 id = it->first;
Anm2LayerAnimation layerAnimation = it->second;
Anm2Layer* layer = &self->anm2->layers[id];
Anm2Frame frame;
Texture* texture = &self->resources->loadedTextures[layer->spritesheetID];
if (!layerAnimation.isVisible || layerAnimation.frames.size() <= 0)
continue;
if (!anm2_frame_from_time(self->anm2, animation, &frame, ANM2_LAYER_ANIMATION, id, self->time))
continue;
if (!frame.isVisible)
continue;
glm::vec2 scale = self->settings->isRootTransform ?
(frame.scale / 100.0f) * (rootFrame.scale / 100.0f) :
(frame.scale / 100.0f);
glm::vec2 position = self->settings->isRootTransform ?
(frame.position + rootFrame.position) :
frame.position;
glm::mat4 pivotTransform = previewTransform;
glm::vec2 previewSize = {(f32)PREVIEW_SIZE.x, (f32)PREVIEW_SIZE.y};
glm::vec2 scaledSize = PREVIEW_PIVOT_SIZE * scale;
glm::vec2 ndcPos = (position - (PREVIEW_PIVOT_SIZE / 2.0f)) / (previewSize / 2.0f);
glm::vec2 ndcScale = scaledSize / (previewSize * 0.5f);
pivotTransform = glm::translate(pivotTransform, glm::vec3(ndcPos, 0.0f));
pivotTransform = glm::scale(pivotTransform, glm::vec3(ndcScale, 1.0f));
f32 vertices[] =
{
0, 0, 0.0f, 0.0f,
1, 0, 1.0f, 0.0f,
1, 1, 1.0f, 1.0f,
0, 1, 0.0f, 1.0f
};
glBindVertexArray(self->textureVAO);
glBindBuffer(GL_ARRAY_BUFFER, self->textureVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, self->resources->textures[TEXTURE_PIVOT].handle);
glUniform1i(glGetUniformLocation(shaderTexture, SHADER_UNIFORM_TEXTURE), 0);
glUniform4fv(glGetUniformLocation(shaderTexture, SHADER_UNIFORM_TINT), 1, value_ptr(PREVIEW_PIVOT_TINT));
glUniform3fv(glGetUniformLocation(shaderTexture, SHADER_UNIFORM_COLOR_OFFSET), 1, value_ptr(PREVIEW_PIVOT_COLOR_OFFSET));
glUniformMatrix4fv(glGetUniformLocation(shaderTexture, SHADER_UNIFORM_TRANSFORM), 1, GL_FALSE, value_ptr(pivotTransform));
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindTexture(GL_TEXTURE_2D, 0);
}
}
/* Nulls */
for (auto & [id, nullAnimation] : animation->nullAnimations)
{
Anm2Frame frame;
if (!nullAnimation.isVisible || nullAnimation.frames.size() <= 0)
continue;
if (!anm2_frame_from_time(self->anm2, animation, &frame, ANM2_NULL_ANIMATION, id, self->time))
continue;
if (!frame.isVisible)
continue;
glm::mat4 nullTransform = previewTransform;
glm::vec2 previewSize = {(f32)PREVIEW_SIZE.x, (f32)PREVIEW_SIZE.y};
glm::vec2 pos = self->settings->isRootTransform ?
frame.position + (rootFrame.position) - (PREVIEW_TARGET_SIZE / 2.0f):
frame.position - (PREVIEW_TARGET_SIZE / 2.0f);
glm::vec2 ndcPos = pos / (previewSize / 2.0f);
glm::vec2 ndcScale = PREVIEW_TARGET_SIZE / (previewSize * 0.5f);
nullTransform = glm::translate(nullTransform, glm::vec3(ndcPos, 0.0f));
nullTransform = glm::scale(nullTransform, glm::vec3(ndcScale, 1.0f));
f32 vertices[] =
{
0, 0, 0.0f, 0.0f,
1, 0, 1.0f, 0.0f,
1, 1, 1.0f, 1.0f,
0, 1, 0.0f, 1.0f
};
glBindVertexArray(self->textureVAO);
glBindBuffer(GL_ARRAY_BUFFER, self->textureVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, self->resources->textures[TEXTURE_TARGET].handle);
glUniform1i(glGetUniformLocation(shaderTexture, SHADER_UNIFORM_TEXTURE), 0);
glUniform4fv(glGetUniformLocation(shaderTexture, SHADER_UNIFORM_TINT), 1, value_ptr(PREVIEW_NULL_TINT));
glUniform3fv(glGetUniformLocation(shaderTexture, SHADER_UNIFORM_COLOR_OFFSET), 1, value_ptr(PREVIEW_NULL_COLOR_OFFSET));
glUniformMatrix4fv(glGetUniformLocation(shaderTexture, SHADER_UNIFORM_TRANSFORM), 1, GL_FALSE, value_ptr(nullTransform));
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindTexture(GL_TEXTURE_2D, 0);
}
}
glUseProgram(0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
} }
void void

View File

@@ -1,16 +1,21 @@
#pragma once #pragma once
#include "anm2.h"
#include "resources.h" #include "resources.h"
#include "input.h" #include "input.h"
#include "settings.h"
static const ivec2 PREVIEW_SIZE = {960, 720}; static const ivec2 PREVIEW_SIZE = {2000, 2000};
static const ivec2 PREVIEW_CENTER = {0, 0}; static const ivec2 PREVIEW_CENTER = {0, 0};
#define PREVIEW_ZOOM_MIN 1 #define PREVIEW_ZOOM_MIN 1.0f
#define PREVIEW_ZOOM_MAX 400 #define PREVIEW_ZOOM_MAX 800.0f
#define PREVIEW_GRID_MIN 1 #define PREVIEW_GRID_MIN 1
#define PREVIEW_GRID_MAX 50 #define PREVIEW_GRID_MAX 50
#define PREVIEW_ZOOM_STEP 10 #define PREVIEW_GRID_OFFSET_MIN 0
#define PREVIEW_GRID_OFFSET_MAX 100
#define PREVIEW_ZOOM_STEP 50
#define PREVIEW
static const f32 PREVIEW_AXIS_VERTICES[] = static const f32 PREVIEW_AXIS_VERTICES[] =
{ {
@@ -20,31 +25,44 @@ static const f32 PREVIEW_AXIS_VERTICES[] =
0.0f, 1.0f 0.0f, 1.0f
}; };
static const GLuint PREVIEW_TEXTURE_INDICES[] = {0, 1, 2, 2, 3, 0};
static const vec2 PREVIEW_PIVOT_SIZE = {6, 6};
static const vec2 PREVIEW_TARGET_SIZE = {16, 16};
static const vec4 PREVIEW_ROOT_TINT = {0.0f, 1.0f, 0.0f, 1.0f};
static const vec3 PREVIEW_ROOT_COLOR_OFFSET = {0.0f, 0.0f, 0.0f};
static const vec4 PREVIEW_NULL_TINT = {0.0f, 0.0f, 1.0f, 1.0f};
static const vec3 PREVIEW_NULL_COLOR_OFFSET = {0.0f, 0.0f, 0.0f};
static const vec4 PREVIEW_PIVOT_TINT = {1.0f, 1.0f, 1.0f, 1.0f};
static const vec3 PREVIEW_PIVOT_COLOR_OFFSET = {0.0f, 0.0f, 0.0f};
struct Preview struct Preview
{ {
GLuint texture; Anm2* anm2 = NULL;
GLuint fbo; Input* input = NULL;
GLuint rbo; Resources* resources = NULL;
GLuint gridVAO; Settings* settings = NULL;
GLuint gridVBO;
GLuint axisVAO; GLuint axisVAO;
GLuint axisVBO; GLuint axisVBO;
Input* input; GLuint fbo;
Resources* resources; GLuint gridVAO;
bool isGrid = false; GLuint gridVBO;
bool isAxis = true; GLuint rbo;
ivec2 viewport = PREVIEW_SIZE; GLuint texture;
f32 zoom = 100; GLuint textureEBO;
vec2 pan = PREVIEW_CENTER; GLuint textureVAO;
ivec2 gridSize = {10, 10}; GLuint textureVBO;
bool isPlaying = false;
f32 time = 0;
ivec2 oldGridOffset = {-1, -1};
ivec2 oldGridSize = {-1, -1}; ivec2 oldGridSize = {-1, -1};
ivec2 viewport = PREVIEW_SIZE;
s32 animationID = -1;
s32 gridVertexCount = -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, Resources* resources, Input* input); void preview_init(Preview* self, Anm2* anm2, Resources* resources, Input* input, 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);

View File

@@ -25,6 +25,7 @@ resources_free(Resources* self)
resources_loaded_textures_free(self); resources_loaded_textures_free(self);
} }
/* Frees loaded textures */
void void
resources_loaded_textures_free(Resources* self) resources_loaded_textures_free(Resources* self)
{ {

161
src/settings.cpp Normal file
View File

@@ -0,0 +1,161 @@
#include "settings.h"
static void _settings_setting_load(Settings* self, char* line);
static void _settings_setting_write(Settings* self, SDL_IOStream* io, SettingsItem type);
/* Load a particular settings from a line */
static void
_settings_setting_load(Settings* self, char* line)
{
for (int i = 0; i < SETTINGS_COUNT; i++)
{
if (strncmp(line, SETTINGS_ENTRIES[i].value, strlen(SETTINGS_ENTRIES[i].value)) == 0)
{
char* value = line + strlen(SETTINGS_ENTRIES[i].value);
void* target = (u8*)self + SETTINGS_ENTRIES[i].offset;
switch (SETTINGS_ENTRIES[i].type)
{
case SETTINGS_TYPE_INT:
case SETTINGS_TYPE_BOOL:
*(s32*)target = atoi(value);
break;
case SETTINGS_TYPE_FLOAT:
*(f32*)target = atof(value);
break;
case SETTINGS_TYPE_STRING:
strncpy((char*)target, value, SETTINGS_BUFFER_ITEM - 1);
((char*)target)[SETTINGS_BUFFER_ITEM - 1] = '\0';
break;
default:
break;
}
return;
}
}
}
/* Writes a particular setting to the current IO */
static void
_settings_setting_write(Settings* self, SDL_IOStream* io, SettingsItem type)
{
char valueBuffer[SETTINGS_BUFFER_ITEM];
SettingsEntry entry = SETTINGS_ENTRIES[type];
u8* selfPointer = (u8*)self;
memset(valueBuffer, '\0', sizeof(valueBuffer));
switch (entry.type)
{
case SETTINGS_TYPE_INT:
snprintf(valueBuffer, SETTINGS_BUFFER_ITEM, entry.format, *(s32*)(selfPointer + entry.offset));
break;
case SETTINGS_TYPE_BOOL:
snprintf(valueBuffer, SETTINGS_BUFFER_ITEM, entry.format, *(bool*)(selfPointer + entry.offset));
break;
case SETTINGS_TYPE_FLOAT:
snprintf(valueBuffer, SETTINGS_BUFFER_ITEM, entry.format, *(f32*)(selfPointer + entry.offset));
break;
case SETTINGS_TYPE_STRING:
snprintf(valueBuffer, SETTINGS_BUFFER_ITEM, entry.value, entry.format, *(char*)(selfPointer + entry.offset));
break;
default:
break;
}
SDL_WriteIO(io, valueBuffer, strlen(valueBuffer));
SDL_WriteIO(io, "\n", strlen("\n"));
}
/* Saves the program's settings to the PATH_SETTINGS file */
void
settings_save(Settings* self)
{
char buffer[SETTINGS_BUFFER];
/* Get the original settings.ini buffer (as previously saved by imgui before this is called) */
memset(buffer, '\0', SETTINGS_BUFFER);
SDL_IOStream* io = SDL_IOFromFile(PATH_SETTINGS, "r");
if (!io)
{
printf(STRING_ERROR_SETTINGS_INIT, PATH_SETTINGS);
return;
}
SDL_ReadIO(io, buffer, SETTINGS_BUFFER);
SDL_CloseIO(io);
io = SDL_IOFromFile(PATH_SETTINGS, "w");
if (!io)
{
printf(STRING_ERROR_SETTINGS_INIT, PATH_SETTINGS);
return;
}
/* [Settings] */
SDL_WriteIO(io, SETTINGS_SECTION, strlen(SETTINGS_SECTION));
SDL_WriteIO(io, "\n", strlen("\n"));
/* Write down all elements */
for (s32 i = 0; i < SETTINGS_COUNT; i++)
_settings_setting_write(self, io, (SettingsItem)i);
SDL_WriteIO(io, "\n", strlen("\n"));
/* specify that the other settings are imgui */
SDL_WriteIO(io, SETTINGS_SECTION_IMGUI, strlen(SETTINGS_SECTION_IMGUI));
SDL_WriteIO(io, "\n", strlen("\n"));
/* Then write original contents */
SDL_WriteIO(io, buffer, strlen(buffer));
SDL_CloseIO(io);
}
/* Loads the settings from the PATH_SETTINGS file */
void
settings_load(Settings* self)
{
char buffer[SETTINGS_BUFFER];
char* line = NULL;
memset(buffer, '\0', SETTINGS_BUFFER);
SDL_IOStream* io = SDL_IOFromFile(PATH_SETTINGS, "r");
if (!io)
{
printf(STRING_ERROR_SETTINGS_INIT, PATH_SETTINGS);
return;
}
size_t bytesRead = SDL_ReadIO(io, buffer, SETTINGS_BUFFER);
SDL_CloseIO(io);
buffer[bytesRead] = '\0';
line = strtok(buffer, "\n");
/* The settings will be the first section in the file */
/* Go through its elements, load them to settings, and go on with your day */
while (line != NULL)
{
if (strcmp(line, SETTINGS_SECTION) == 0)
{
line = strtok(NULL, "\n");
continue;
}
_settings_setting_load(self, line);
/* get out here */
if (strcmp(line, SETTINGS_SECTION_IMGUI) == 0)
break;
line = strtok(NULL, "\n");
}
}

115
src/settings.h Normal file
View File

@@ -0,0 +1,115 @@
#pragma once
#include "COMMON.h"
#define SETTINGS_BUFFER 0xFFFF
#define SETTINGS_BUFFER_ITEM 0xFF
#define SETTINGS_SECTION "[Settings]"
#define SETTINGS_SECTION_IMGUI "# Dear ImGui"
enum SettingsValueType
{
SETTINGS_TYPE_INT,
SETTINGS_TYPE_FLOAT,
SETTINGS_TYPE_BOOL,
SETTINGS_TYPE_STRING
};
struct SettingsEntry
{
const char* value;
const char* format;
SettingsValueType type;
s32 offset;
};
#define SETTINGS_COUNT (SETTINGS_BACKGROUND_COLOR_A + 1)
enum SettingsItem
{
SETTINGS_WINDOW_W,
SETTINGS_WINDOW_H,
SETTINGS_IS_AXIS,
SETTINGS_IS_GRID,
SETTINGS_IS_ROOT_TRANSFORM,
SETTINGS_IS_SHOW_PIVOT,
SETTINGS_PAN_X,
SETTINGS_PAN_Y,
SETTINGS_ZOOM,
SETTINGS_GRID_SIZE_X,
SETTINGS_GRID_SIZE_Y,
SETTINGS_GRID_OFFSET_X,
SETTINGS_GRID_OFFSET_Y,
SETTINGS_GRID_COLOR_R,
SETTINGS_GRID_COLOR_G,
SETTINGS_GRID_COLOR_B,
SETTINGS_GRID_COLOR_A,
SETTINGS_AXIS_COLOR_R,
SETTINGS_AXIS_COLOR_G,
SETTINGS_AXIS_COLOR_B,
SETTINGS_AXIS_COLOR_A,
SETTINGS_BACKGROUND_COLOR_R,
SETTINGS_BACKGROUND_COLOR_G,
SETTINGS_BACKGROUND_COLOR_B,
SETTINGS_BACKGROUND_COLOR_A
};
struct Settings
{
s32 windowW = 1920;
s32 windowH = 1080;
bool isAxis = true;
bool isGrid = true;
bool isRootTransform = false;
bool isShowPivot = false;
f32 panX = 0.0f;
f32 panY = 0.0f;
f32 zoom = 200.0f;
s32 gridSizeX = 10;
s32 gridSizeY = 10;
s32 gridOffsetX = 10;
s32 gridOffsetY = 10;
f32 gridColorR = 1.0f;
f32 gridColorG = 1.0f;
f32 gridColorB = 1.0f;
f32 gridColorA = 0.125f;
f32 axisColorR = 1.0f;
f32 axisColorG = 1.0f;
f32 axisColorB = 1.0f;
f32 axisColorA = 0.5f;
f32 backgroundColorR = 0.113f;
f32 backgroundColorG = 0.184f;
f32 backgroundColorB = 0.286f;
f32 backgroundColorA = 1.0f;
};
static const SettingsEntry SETTINGS_ENTRIES[SETTINGS_COUNT] =
{
{"windowW=", "windowW=%i", SETTINGS_TYPE_INT, offsetof(Settings, windowW)},
{"windowH=", "windowH=%i", SETTINGS_TYPE_INT, offsetof(Settings, windowH)},
{"isAxis=", "isAxis=%i", SETTINGS_TYPE_BOOL, offsetof(Settings, isAxis)},
{"isGrid=", "isGrid=%i", SETTINGS_TYPE_BOOL, offsetof(Settings, isGrid)},
{"isRootTransform=", "isRootTransform=%i", SETTINGS_TYPE_BOOL, offsetof(Settings, isRootTransform)},
{"isShowPivot=", "isShowPivot=%i", SETTINGS_TYPE_BOOL, offsetof(Settings, isShowPivot)},
{"panX=", "panX=%f", SETTINGS_TYPE_FLOAT, offsetof(Settings, panX)},
{"panY=", "panY=%f", SETTINGS_TYPE_FLOAT, offsetof(Settings, panY)},
{"zoom=", "zoom=%f", SETTINGS_TYPE_FLOAT, offsetof(Settings, zoom)},
{"gridSizeX=", "gridSizeX=%i", SETTINGS_TYPE_INT, offsetof(Settings, gridSizeX)},
{"gridSizeY=", "gridSizeY=%i", SETTINGS_TYPE_INT, offsetof(Settings, gridSizeY)},
{"gridOffsetX=", "gridOffsetX=%i", SETTINGS_TYPE_INT, offsetof(Settings, gridOffsetX)},
{"gridOffsetY=", "gridOffsetY=%i", SETTINGS_TYPE_INT, offsetof(Settings, gridOffsetY)},
{"gridColorR=", "gridColorR=%f", SETTINGS_TYPE_FLOAT, offsetof(Settings, gridColorR)},
{"gridColorG=", "gridColorG=%f", SETTINGS_TYPE_FLOAT, offsetof(Settings, gridColorG)},
{"gridColorB=", "gridColorB=%f", SETTINGS_TYPE_FLOAT, offsetof(Settings, gridColorB)},
{"gridColorA=", "gridColorA=%f", SETTINGS_TYPE_FLOAT, offsetof(Settings, gridColorA)},
{"axisColorR=", "axisColorR=%f", SETTINGS_TYPE_FLOAT, offsetof(Settings, axisColorR)},
{"axisColorG=", "axisColorG=%f", SETTINGS_TYPE_FLOAT, offsetof(Settings, axisColorG)},
{"axisColorB=", "axisColorB=%f", SETTINGS_TYPE_FLOAT, offsetof(Settings, axisColorB)},
{"axisColorA=", "axisColorA=%f", SETTINGS_TYPE_FLOAT, offsetof(Settings, axisColorA)},
{"backgroundColorR=", "backgroundColorR=%f", SETTINGS_TYPE_FLOAT, offsetof(Settings, backgroundColorR)},
{"backgroundColorG=", "backgroundColorG=%f", SETTINGS_TYPE_FLOAT, offsetof(Settings, backgroundColorG)},
{"backgroundColorB=", "backgroundColorB=%f", SETTINGS_TYPE_FLOAT, offsetof(Settings, backgroundColorB)},
{"backgroundColorA=", "backgroundColorA=%f", SETTINGS_TYPE_FLOAT, offsetof(Settings, backgroundColorA)}
};
void settings_save(Settings* self);
void settings_load(Settings* self);

View File

@@ -29,6 +29,8 @@ _tick(State* state)
} }
} }
SDL_GetWindowSize(state->window, &state->settings.windowW, &state->settings.windowH);
input_tick(&state->input); input_tick(&state->input);
preview_tick(&state->preview); preview_tick(&state->preview);
dialog_tick(&state->dialog); dialog_tick(&state->dialog);
@@ -47,6 +49,15 @@ _draw(State* state)
void void
init(State* state) init(State* state)
{ {
/* set start working directory */
std::filesystem::path startPath = std::filesystem::current_path();
memset(state->startPath, '\0', PATH_MAX - 1);
strncpy(state->startPath, startPath.c_str(), PATH_MAX - 1);
settings_load(&state->settings);
printf(STRING_INFO_INIT); printf(STRING_INFO_INIT);
if (!SDL_Init(SDL_INIT_VIDEO)) if (!SDL_Init(SDL_INIT_VIDEO))
@@ -60,15 +71,21 @@ init(State* state)
SDL_CreateWindowAndRenderer SDL_CreateWindowAndRenderer
( (
STRING_WINDOW_TITLE, STRING_WINDOW_TITLE,
WINDOW_WIDTH, state->settings.windowW,
WINDOW_HEIGHT, state->settings.windowH,
WINDOW_FLAGS, WINDOW_FLAGS,
&state->window, &state->window,
&state->renderer &state->renderer
); );
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
state->glContext = SDL_GL_CreateContext(state->window); state->glContext = SDL_GL_CreateContext(state->window);
printf(STRING_INFO_OPENGL, glGetString(GL_VERSION));
if (!state->glContext) if (!state->glContext)
{ {
printf(STRING_ERROR_GL_CONTEXT_INIT, SDL_GetError()); printf(STRING_ERROR_GL_CONTEXT_INIT, SDL_GetError());
@@ -76,24 +93,18 @@ init(State* state)
} }
glewInit(); glewInit();
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_DEPTH_TEST);
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); dialog_init(&state->dialog, &state->anm2, &state->resources, state->window);
preview_init(&state->preview, &state->resources, &state->input); preview_init(&state->preview, &state->anm2, &state->resources, &state->input, &state->settings);
if (state->isArgument)
anm2_deserialize(&state->anm2, &state->resources, state->argument);
else
anm2_new(&state->anm2);
window_title_from_anm2_set(state->window, &state->anm2);
imgui_init imgui_init
( (
&state->imgui, &state->imgui,
@@ -102,9 +113,17 @@ init(State* state)
&state->input, &state->input,
&state->anm2, &state->anm2,
&state->preview, &state->preview,
&state->settings,
state->window, state->window,
&state->glContext &state->glContext
); );
if (state->isArgument)
anm2_deserialize(&state->anm2, &state->resources, state->argument);
else
anm2_new(&state->anm2);
window_title_from_anm2_set(state->window, &state->anm2);
} }
void void
@@ -129,7 +148,11 @@ loop(State* state)
void void
quit(State* state) quit(State* state)
{ {
/* return to base path */
std::filesystem::current_path(state->startPath);
imgui_free(&state->imgui); imgui_free(&state->imgui);
settings_save(&state->settings);
preview_free(&state->preview); preview_free(&state->preview);
resources_free(&state->resources); resources_free(&state->resources);

View File

@@ -1,11 +1,9 @@
#pragma once #pragma once
#include "shader.h"
#include "imgui.h" #include "imgui.h"
#define TICK_DELAY 16 #define WINDOW_WIDTH 1920
#define WINDOW_WIDTH 1600 #define WINDOW_HEIGHT 1080
#define WINDOW_HEIGHT 900
#define WINDOW_FLAGS SDL_WINDOW_RESIZABLE #define WINDOW_FLAGS SDL_WINDOW_RESIZABLE
struct State struct State
@@ -19,7 +17,9 @@ struct State
Preview preview; Preview preview;
Anm2 anm2; Anm2 anm2;
Resources resources; Resources resources;
Settings settings;
char argument[PATH_MAX] = STRING_EMPTY; char argument[PATH_MAX] = STRING_EMPTY;
char startPath[PATH_MAX] = STRING_EMPTY;
bool isArgument = false; bool isArgument = false;
u64 tick = 0; u64 tick = 0;
u64 lastTick = 0; u64 lastTick = 0;

View File

@@ -7,6 +7,7 @@ struct Texture
GLuint handle = 0; GLuint handle = 0;
ivec2 size = {0, 0}; ivec2 size = {0, 0};
s32 channels = -1; s32 channels = -1;
bool isInvalid = false;
}; };
void texture_gl_set(Texture* self, void* data); void texture_gl_set(Texture* self, void* data);