visuals and a lot of other things
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -8,3 +8,6 @@
|
||||
[submodule "include/tinyxml2"]
|
||||
path = include/tinyxml2
|
||||
url = https://github.com/leethomason/tinyxml2
|
||||
[submodule "include/inih"]
|
||||
path = include/inih
|
||||
url = https://github.com/benhoyt/inih
|
||||
|
@ -1,5 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(anm2ed CXX)
|
||||
project(anm2ed C CXX)
|
||||
|
||||
# Gather project sources
|
||||
file(GLOB SOURCES
|
||||
@ -10,12 +10,13 @@ file(GLOB SOURCES
|
||||
"include/imgui/backends/imgui_impl_sdl3.cpp"
|
||||
"include/imgui/backends/imgui_impl_opengl3.cpp"
|
||||
"include/tinyxml2/tinyxml2.cpp"
|
||||
"include/inih/ini.c"
|
||||
"${PROJECT_SOURCE_DIR}/src/*.cpp"
|
||||
)
|
||||
|
||||
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")
|
||||
|
||||
|
69
settings.ini
Normal file
69
settings.ini
Normal 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
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
@ -18,6 +19,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <ranges>
|
||||
#include <vector>
|
||||
@ -46,6 +48,13 @@ using namespace glm; // fuck you
|
||||
#define MAX(x, max) (x > max ? max : x)
|
||||
#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 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; }
|
||||
|
218
src/RESOURCES.h
218
src/RESOURCES.h
@ -9,6 +9,13 @@ struct TextureData
|
||||
u32 length;
|
||||
};
|
||||
|
||||
|
||||
static const unsigned char texture_dummy[] =
|
||||
{
|
||||
0xFF
|
||||
};
|
||||
static const unsigned int texture_dummy_len = 1;
|
||||
|
||||
static const unsigned char texture_eye_closed[] = {
|
||||
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
|
||||
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
|
||||
};
|
||||
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
|
||||
{
|
||||
TEXTURE_DUMMY,
|
||||
TEXTURE_EYE_OPEN,
|
||||
TEXTURE_EYE_CLOSED,
|
||||
TEXTURE_ANIMATION,
|
||||
@ -282,11 +433,21 @@ enum TextureType
|
||||
TEXTURE_RECT_SHOW,
|
||||
TEXTURE_RECT_HIDE,
|
||||
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] =
|
||||
{
|
||||
{texture_dummy, texture_dummy_len},
|
||||
{texture_eye_open, texture_eye_open_len},
|
||||
{texture_eye_closed, texture_eye_closed_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_arrow_up, texture_arrow_up_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 */
|
||||
@ -309,37 +479,61 @@ struct ShaderData
|
||||
const char* fragment;
|
||||
};
|
||||
|
||||
#define SHADER_COUNT (SHADER + 1)
|
||||
#define SHADER_COUNT (SHADER_TEXTURE + 1)
|
||||
enum ShaderType
|
||||
{
|
||||
SHADER
|
||||
SHADER_LINE,
|
||||
SHADER_TEXTURE
|
||||
};
|
||||
|
||||
static const char SHADER_VERTEX[] =
|
||||
"#version 330 core\n" \
|
||||
"layout (location = 0)\n" \
|
||||
"in vec2 i_position;\n" \
|
||||
"layout (location = 0) 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" \
|
||||
"\n" \
|
||||
"void main()\n" \
|
||||
"{\n" \
|
||||
" vec4 pos = vec4(i_position, 0.0, 1.0);\n" \
|
||||
" gl_Position = u_transform * pos;\n" \
|
||||
" i_uv_out = i_uv;\n" \
|
||||
" gl_Position = u_transform * vec4(i_position, 0.0, 1.0);\n" \
|
||||
"}\n";
|
||||
|
||||
static const char SHADER_FRAGMENT[] = "#version 330 core\n" \
|
||||
"out vec4 FragColor;\n" \
|
||||
static const char SHADER_TEXTURE_FRAGMENT[] =
|
||||
"#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" \
|
||||
"\n" \
|
||||
"void main()\n" \
|
||||
"{\n" \
|
||||
" FragColor = u_color;\n" \
|
||||
" o_fragColor = u_color;\n" \
|
||||
"}\n";
|
||||
|
||||
static const char SHADER_UNIFORM_COLOR[] = "u_color";
|
||||
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] =
|
||||
{
|
||||
{SHADER_VERTEX, SHADER_FRAGMENT}
|
||||
{SHADER_VERTEX, SHADER_FRAGMENT},
|
||||
{SHADER_VERTEX, SHADER_TEXTURE_FRAGMENT}
|
||||
};
|
||||
|
@ -13,6 +13,7 @@
|
||||
#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_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_QUIT "[INFO] Exited\n"
|
||||
@ -25,6 +26,7 @@
|
||||
#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_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_FREE "[INFO] Freed Dear Imgui\n"
|
||||
@ -54,14 +56,6 @@
|
||||
#define STRING_IMGUI_FILE_SAVE "Save"
|
||||
#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_ANIMATION_LABEL "##Animation"
|
||||
#define STRING_IMGUI_ANIMATIONS_ADD "Add"
|
||||
@ -95,13 +89,20 @@
|
||||
#define STRING_IMGUI_FRAME_PROPERTIES_DURATION "Duration"
|
||||
#define STRING_IMGUI_FRAME_PROPERTIES_TINT "Tint"
|
||||
#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_LABEL "##Animation Preview"
|
||||
#define STRING_IMGUI_ANIMATION_PREVIEW_SETTINGS "##Animation Preview Settings"
|
||||
#define STRING_IMGUI_ANIMATION_PREVIEW_GRID_SETTINGS "##Grid Settings"
|
||||
#define STRING_IMGUI_ANIMATION_PREVIEW_GRID "Grid"
|
||||
#define STRING_IMGUI_ANIMATION_PREVIEW_GRID_SIZE "##Grid Size"
|
||||
#define STRING_IMGUI_ANIMATION_PREVIEW_GRID_SIZE "Size"
|
||||
#define STRING_IMGUI_ANIMATION_PREVIEW_GRID_OFFSET "Offset"
|
||||
#define STRING_IMGUI_ANIMATION_PREVIEW_GRID_COLOR "Color"
|
||||
#define STRING_IMGUI_ANIMATION_PREVIEW_VIEW_SETTINGS "##View Settings"
|
||||
#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_AXIS "Axes"
|
||||
#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_TIMELINE "Timeline"
|
||||
#define STRING_IMGUI_TIMELINE_ELEMENT_SHIFT_ABOVE "Shift Above"
|
||||
#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_ELEMENT_FORMAT "#%i %s"
|
||||
#define STRING_IMGUI_TIMELINE_SPRITESHEET_FORMAT "#%i"
|
||||
@ -130,6 +134,9 @@
|
||||
#define STRING_IMGUI_TIMELINE_PLAY "|> Play"
|
||||
#define STRING_IMGUI_TIMELINE_PAUSE "|| Pause"
|
||||
#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_FIT_ANIMATION_LENGTH "= Fit 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_ELEMENT_TIMELINE "Element Timeline"
|
||||
#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_MENU "Element Add Menu"
|
||||
#define STRING_IMGUI_TIMELINE_ELEMENT_ADD_MENU_LAYER "Add Layer..."
|
||||
#define STRING_IMGUI_TIMELINE_ELEMENT_ADD_MENU_NULL "Add Null..."
|
||||
#define STRING_IMGUI_TIMELINE_ELEMENT_REMOVE "Remove 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_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_CENTER_VIEW "Centers the preview's pan."
|
||||
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_GRID "Toggles grid visibility on the animation preview."
|
||||
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_GRID_SIZE "Changes the grid's size, in pixels."
|
||||
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_GRID_COLOR "Changes the animation preview grid color."
|
||||
#define STRING_IMGUI_TOOLTIP_ANIMATION_PREVIEW_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_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_REMOVE "Removes the selected event."
|
||||
#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_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_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_PIVOT "Change the pivot 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_TINT "Change the tint of the frame."
|
||||
#define STRING_IMGUI_TOOLTIP_FRAME_PROPERTIES_VISIBLE "Toggles the visibility of the frame."
|
||||
#define STRING_IMGUI_TOOLTIP_PROPERTIES_CREATED_BY "Change the author of the animation."
|
||||
#define STRING_IMGUI_TOOLTIP_PROPERTIES_CREATED_ON_NOW "Set the date of creation to the current system time."
|
||||
#define STRING_IMGUI_TOOLTIP_PROPERTIES_FPS "Change the FPS of the animation."
|
||||
#define STRING_IMGUI_TOOLTIP_SPRITESHEETS_ADD "Opens the file dialog to load in a new spritesheet."
|
||||
#define STRING_IMGUI_TOOLTIP_SPRITESHEETS_RELOAD "Reloads the selected spritesheet."
|
||||
#define STRING_IMGUI_TOOLTIP_SPRITESHEETS_REMOVE "Removes the selected spritesheet."
|
||||
#define STRING_IMGUI_TOOLTIP_SPRITESHEETS_REPLACE "Replaces the selected spritesheet; opens up the file dialog."
|
||||
#define STRING_IMGUI_TOOLTIP_SPRITESHEETS_SELECT "Select the spritesheet element."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_ANIMATION_LENGTH "Changes the current animation's length."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_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_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_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_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_UP "Shift this timeline element above.\nElements with higher indices will display further behind."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_SPRITESHEET "Click to change the spritesheet the layer is using."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_ELEMENT_TRIGGERS "This is the animation's Triggers.\nTriggers are special activations; each is bound to an Event."
|
||||
#define STRING_IMGUI_TOOLTIP_TIMELINE_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_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_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_PLAY "Plays the animation."
|
||||
|
||||
#define STRING_OPENGL_VERSION "#version 330"
|
||||
#define STRING_OPENGL_VERSION "#version 330"
|
||||
|
||||
#define PATH_SETTINGS "settings.ini"
|
||||
|
179
src/anm2.cpp
179
src/anm2.cpp
@ -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_DELAY], frame.delay); /* Delay */
|
||||
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_GREEN_TINT], frame.tintRGBA.g); /* GreenTint */
|
||||
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_BLUE_TINT], frame.tintRGBA.b); /* BlueTint */
|
||||
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_ALPHA_TINT], frame.tintRGBA.a); /* AlphaTint */
|
||||
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_RED_OFFSET], frame.offsetRGB.r); /* RedOffset */
|
||||
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_GREEN_OFFSET], frame.offsetRGB.g); /* GreenOffset */
|
||||
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_BLUE_OFFSET], frame.offsetRGB.b); /* BlueOffset */
|
||||
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], COLOR_FLOAT_TO_INT(frame.tintRGBA.g)); /* GreenTint */
|
||||
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], COLOR_FLOAT_TO_INT(frame.tintRGBA.a)); /* AlphaTint */
|
||||
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], COLOR_FLOAT_TO_INT(frame.offsetRGB.g)); /* GreenOffset */
|
||||
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_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_DELAY], frame.delay); /* Delay */
|
||||
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_GREEN_TINT], frame.tintRGBA.g); /* GreenTint */
|
||||
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_BLUE_TINT], frame.tintRGBA.b); /* BlueTint */
|
||||
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_ALPHA_TINT], frame.tintRGBA.a); /* AlphaTint */
|
||||
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_RED_OFFSET], frame.offsetRGB.r); /* RedOffset */
|
||||
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_GREEN_OFFSET], frame.offsetRGB.g); /* GreenOffset */
|
||||
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_BLUE_OFFSET], frame.offsetRGB.b); /* BlueOffset */
|
||||
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], COLOR_FLOAT_TO_INT(frame.tintRGBA.g)); /* GreenTint */
|
||||
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], COLOR_FLOAT_TO_INT(frame.tintRGBA.a)); /* AlphaTint */
|
||||
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], COLOR_FLOAT_TO_INT(frame.offsetRGB.g)); /* GreenOffset */
|
||||
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_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_DELAY], frame.delay); /* Delay */
|
||||
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_GREEN_TINT], frame.tintRGBA.g); /* GreenTint */
|
||||
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_BLUE_TINT], frame.tintRGBA.b); /* BlueTint */
|
||||
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_ALPHA_TINT], frame.tintRGBA.a); /* AlphaTint */
|
||||
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_RED_OFFSET], frame.offsetRGB.r); /* RedOffset */
|
||||
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_GREEN_OFFSET], frame.offsetRGB.g); /* GreenOffset */
|
||||
frameElement->SetAttribute(ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_BLUE_OFFSET], frame.offsetRGB.b); /* BlueOffset */
|
||||
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], COLOR_FLOAT_TO_INT(frame.tintRGBA.g)); /* GreenTint */
|
||||
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], COLOR_FLOAT_TO_INT(frame.tintRGBA.a)); /* AlphaTint */
|
||||
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], COLOR_FLOAT_TO_INT(frame.offsetRGB.g)); /* GreenOffset */
|
||||
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_INTERPOLATED], frame.isInterpolated); /* Interpolated */
|
||||
|
||||
@ -341,6 +341,7 @@ anm2_deserialize(Anm2* self, Resources* resources, const char* path)
|
||||
Anm2Layer tempLayer;
|
||||
Anm2Spritesheet tempSpritesheet;
|
||||
Anm2Event tempEvent;
|
||||
char lastSpritesheetPath[PATH_MAX];
|
||||
|
||||
*self = Anm2{};
|
||||
|
||||
@ -354,7 +355,8 @@ anm2_deserialize(Anm2* self, Resources* resources, const char* path)
|
||||
|
||||
resources_loaded_textures_free(resources);
|
||||
strncpy(self->path, path, PATH_MAX - 1);
|
||||
|
||||
working_directory_from_path_set(path);
|
||||
|
||||
root = document.FirstChildElement(ANM2_ELEMENT_STRINGS[ANM2_ELEMENT_ANIMATED_ACTOR]);
|
||||
element = root;
|
||||
|
||||
@ -472,8 +474,8 @@ anm2_deserialize(Anm2* self, Resources* resources, const char* path)
|
||||
}
|
||||
break;
|
||||
case ANM2_ATTRIBUTE_PATH:
|
||||
strncpy(lastSpritesheet->path, attribute->Value(), PATH_MAX - 1);
|
||||
anm2_spritesheet_texture_load(self, resources, attribute->Value(), id);
|
||||
/* Make path lowercase */
|
||||
strncpy(lastSpritesheetPath, attribute->Value(), PATH_MAX - 1);
|
||||
break;
|
||||
case ANM2_ATTRIBUTE_NAME:
|
||||
switch (anm2Element)
|
||||
@ -566,25 +568,25 @@ anm2_deserialize(Anm2* self, Resources* resources, const char* path)
|
||||
}
|
||||
break;
|
||||
case ANM2_ATTRIBUTE_RED_TINT:
|
||||
lastFrame->tintRGBA.r = atof(attribute->Value());
|
||||
lastFrame->tintRGBA.r = COLOR_INT_TO_FLOAT(atoi(attribute->Value()));
|
||||
break;
|
||||
case ANM2_ATTRIBUTE_GREEN_TINT:
|
||||
lastFrame->tintRGBA.g = atof(attribute->Value());
|
||||
lastFrame->tintRGBA.g = COLOR_INT_TO_FLOAT(atoi(attribute->Value()));
|
||||
break;
|
||||
case ANM2_ATTRIBUTE_BLUE_TINT:
|
||||
lastFrame->tintRGBA.b = atof(attribute->Value());
|
||||
lastFrame->tintRGBA.b = COLOR_INT_TO_FLOAT(atoi(attribute->Value()));
|
||||
break;
|
||||
case ANM2_ATTRIBUTE_ALPHA_TINT:
|
||||
lastFrame->tintRGBA.a = atof(attribute->Value());
|
||||
lastFrame->tintRGBA.a = COLOR_INT_TO_FLOAT(atoi(attribute->Value()));
|
||||
break;
|
||||
case ANM2_ATTRIBUTE_RED_OFFSET:
|
||||
lastFrame->offsetRGB.r = atof(attribute->Value());
|
||||
lastFrame->offsetRGB.r = COLOR_INT_TO_FLOAT(atoi(attribute->Value()));
|
||||
break;
|
||||
case ANM2_ATTRIBUTE_GREEN_OFFSET:
|
||||
lastFrame->offsetRGB.g = atof(attribute->Value());
|
||||
lastFrame->offsetRGB.g = COLOR_INT_TO_FLOAT(atoi(attribute->Value()));
|
||||
break;
|
||||
case ANM2_ATTRIBUTE_BLUE_OFFSET:
|
||||
lastFrame->offsetRGB.b = atof(attribute->Value());
|
||||
lastFrame->offsetRGB.b = COLOR_INT_TO_FLOAT(atoi(attribute->Value()));
|
||||
break;
|
||||
case ANM2_ATTRIBUTE_ROTATION:
|
||||
lastFrame->rotation = atof(attribute->Value());
|
||||
@ -615,6 +617,13 @@ anm2_deserialize(Anm2* self, Resources* resources, const char* path)
|
||||
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 */
|
||||
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);
|
||||
|
||||
return true;
|
||||
@ -702,12 +709,19 @@ anm2_animation_add(Anm2* self)
|
||||
|
||||
/* match layers */
|
||||
for (auto & [layerID, layer] : self->layers)
|
||||
{
|
||||
animation.layerAnimations[layerID] = Anm2LayerAnimation{};
|
||||
}
|
||||
|
||||
/* match 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;
|
||||
|
||||
return id;
|
||||
@ -732,10 +746,99 @@ anm2_spritesheet_texture_load(Anm2* self, Resources* resources, const char* path
|
||||
{
|
||||
Texture texture;
|
||||
|
||||
/* free texture if it exists */
|
||||
if (resources->loadedTextures.find(id) != resources->loadedTextures.end())
|
||||
/* free texture if it exists, and if it's not texture error */
|
||||
if
|
||||
(
|
||||
resources->loadedTextures.find(id) != resources->loadedTextures.end() &&
|
||||
resources->loadedTextures[id].handle != resources->textures[TEXTURE_ERROR].handle
|
||||
)
|
||||
texture_free(&resources->loadedTextures[id]);
|
||||
|
||||
texture_from_path_init(&texture, path);
|
||||
resources->loadedTextures[id] = texture;
|
||||
if (texture_from_path_init(&texture, path))
|
||||
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;
|
||||
}
|
22
src/anm2.h
22
src/anm2.h
@ -11,8 +11,9 @@
|
||||
#define ANM2_PATH_FORMATTED_MAX PATH_MAX + 0xFF
|
||||
#define ANM2_BUFFER_MAX 0xFFFFF
|
||||
#define ANM2_FPS_MIN 0
|
||||
#define ANM2_FPS_DEFAULT 30
|
||||
#define ANM2_FPS_MAX 60
|
||||
#define ANM2_FPS_MAX 120
|
||||
#define ANM2_FRAME_NUM_MIN 1
|
||||
#define ANM2_FRAME_NUM_MAX 1000000
|
||||
|
||||
/* Elements */
|
||||
#define ANM2_ELEMENT_LIST \
|
||||
@ -114,7 +115,7 @@ enum Anm2AnimationType
|
||||
ANM2_ROOT_ANIMATION,
|
||||
ANM2_LAYER_ANIMATION,
|
||||
ANM2_NULL_ANIMATION,
|
||||
ANM2_TRIGGERS
|
||||
ANM2_TRIGGER
|
||||
};
|
||||
|
||||
struct Anm2Spritesheet
|
||||
@ -154,10 +155,10 @@ struct Anm2Frame
|
||||
vec2 crop = {0.0f, 0.0f};
|
||||
vec2 pivot = {0.0f, 0.0f};
|
||||
vec2 position = {0.0f, 0.0f};
|
||||
vec2 size = {1.0f, 1.0f};
|
||||
vec2 scale = {1.0f, 1.0f};
|
||||
ivec3 offsetRGB = {0, 0, 0};
|
||||
ivec4 tintRGBA = {255, 255, 255, 255};
|
||||
vec2 size = {0.0f, 0.0f};
|
||||
vec2 scale = {100.0f, 100.0f};
|
||||
vec3 offsetRGB = {0.0f, 0.0f, 0.0f};
|
||||
vec4 tintRGBA = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
};
|
||||
|
||||
struct Anm2LayerAnimation
|
||||
@ -186,7 +187,7 @@ struct Anm2Triggers
|
||||
|
||||
struct Anm2Animation
|
||||
{
|
||||
s32 frameNum = 0;
|
||||
s32 frameNum = ANM2_FRAME_NUM_MIN;
|
||||
char name[ANM2_STRING_MAX] = STRING_ANM2_NEW_ANIMATION;
|
||||
bool isLoop = true;
|
||||
Anm2RootAnimation rootAnimation;
|
||||
@ -198,7 +199,7 @@ struct Anm2Animation
|
||||
struct Anm2
|
||||
{
|
||||
char path[PATH_MAX] = STRING_EMPTY;
|
||||
s32 fps = ANM2_FPS_DEFAULT;
|
||||
s32 fps = 30;
|
||||
s32 version = 0;
|
||||
char createdBy[ANM2_STRING_MAX] = STRING_ANM2_CREATED_BY_DEFAULT;
|
||||
char createdOn[ANM2_STRING_MAX] = STRING_EMPTY;
|
||||
@ -220,4 +221,5 @@ void anm2_new(Anm2* self);
|
||||
void anm2_created_on_set(Anm2* self);
|
||||
s32 anm2_animation_add(Anm2* self);
|
||||
void anm2_animation_remove(Anm2* self, s32 id);
|
||||
void anm2_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);
|
||||
|
@ -16,14 +16,14 @@ _dialog_callback(void* userdata, const char* const* filelist, s32 filter)
|
||||
}
|
||||
else
|
||||
self->isSelected = false;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
dialog_init(Dialog* self, Anm2* anm2, Resources* resources)
|
||||
dialog_init(Dialog* self, Anm2* anm2, Resources* resources, SDL_Window* window)
|
||||
{
|
||||
self->anm2 = anm2;
|
||||
self->resources = resources;
|
||||
self->window = window;
|
||||
}
|
||||
|
||||
/* Opens file dialog for user to pick anm2 files */
|
||||
@ -76,11 +76,13 @@ dialog_tick(Dialog* self)
|
||||
switch (self->type)
|
||||
{
|
||||
case DIALOG_ANM2_OPEN:
|
||||
anm2_deserialize(self->anm2, self->resources, relativePath);
|
||||
resources_loaded_textures_free(self->resources);
|
||||
anm2_deserialize(self->anm2, self->resources, self->path);
|
||||
window_title_from_anm2_set(self->window, self->anm2);
|
||||
break;
|
||||
case DIALOG_ANM2_SAVE:
|
||||
anm2_serialize(self->anm2, relativePath);
|
||||
window_title_from_anm2_set(self->window, self->anm2);
|
||||
break;
|
||||
case DIALOG_PNG_OPEN:
|
||||
id = map_next_id_get(self->resources->loadedTextures);
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "anm2.h"
|
||||
#include "resources.h"
|
||||
#include "window.h"
|
||||
|
||||
static const SDL_DialogFileFilter DIALOG_FILE_FILTER_ANM2[] =
|
||||
{
|
||||
@ -26,13 +27,14 @@ struct Dialog
|
||||
{
|
||||
Anm2* anm2 = NULL;
|
||||
Resources* resources = NULL;
|
||||
SDL_Window* window = NULL;
|
||||
s32 replaceID = -1;
|
||||
enum DialogType type = DIALOG_NONE;
|
||||
char path[PATH_MAX] = "";
|
||||
bool isSelected = false;
|
||||
};
|
||||
|
||||
void dialog_init(Dialog* self, Anm2* anm2, Resources* resources);
|
||||
void dialog_init(Dialog* self, Anm2* anm2, Resources* resources, SDL_Window* window);
|
||||
void dialog_anm2_open(Dialog* self);
|
||||
void dialog_png_open(Dialog* self);
|
||||
void dialog_png_replace(Dialog* self);
|
||||
|
1659
src/imgui.cpp
1659
src/imgui.cpp
File diff suppressed because it is too large
Load Diff
49
src/imgui.h
49
src/imgui.h
@ -5,6 +5,7 @@
|
||||
#include "preview.h"
|
||||
#include "window.h"
|
||||
#include "input.h"
|
||||
#include "settings.h"
|
||||
|
||||
#define IMGUI_IMPL_OPENGL_LOADER_CUSTOM
|
||||
#define IMGUI_ENABLE_DOCKING
|
||||
@ -15,34 +16,50 @@
|
||||
|
||||
#define IMGUI_DRAG_SPEED 1.0
|
||||
#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_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 ImVec2 IMGUI_ANIMATION_PREVIEW_SETTINGS_SIZE = {1280, 80};
|
||||
static const ImVec2 IMGUI_ANIMATION_PREVIEW_SETTINGS_CHILD_SIZE = {150, 64};
|
||||
static const ImVec2 IMGUI_ANIMATION_PREVIEW_POSITION = {8, 110};
|
||||
static const ImVec2 IMGUI_ANIMATION_PREVIEW_SETTINGS_SIZE = {1280, 105};
|
||||
static const ImVec2 IMGUI_ANIMATION_PREVIEW_SETTINGS_CHILD_SIZE = {175, 85};
|
||||
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_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_SPRITESHEET_ID_SIZE = {40, 20};
|
||||
static const ImVec2 IMGUI_TIMELINE_SHIFT_ARROWS_SIZE = {64, 40};
|
||||
static const ImVec2 IMGUI_TIMELINE_ELEMENT_NAME_SIZE = {85, 20};
|
||||
|
||||
static const ImVec2 IMGUI_SPRITESHEET_SIZE = {0, 150};
|
||||
static const ImVec2 IMGUI_SPRITESHEET_PREVIEW_SIZE = {100, 100};
|
||||
static const ImVec2 IMGUI_ICON_SIZE = {16, 16};
|
||||
static const ImVec2 IMGUI_ICON_SMALL_SIZE = {8, 8};
|
||||
static const ImVec2 IMGUI_ICON_DUMMY_SIZE = {20, 16};
|
||||
static const ImVec2 IMGUI_ICON_BUTTON_SIZE = {24, 24};
|
||||
static const ImVec2 IMGUI_IMAGE_TARGET_SIZE = {125, 125};
|
||||
static const ImVec2 IMGUI_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)
|
||||
|
||||
struct Imgui
|
||||
@ -54,6 +71,15 @@ struct Imgui
|
||||
Preview* preview = NULL;
|
||||
SDL_Window* window = 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
|
||||
@ -64,6 +90,7 @@ void imgui_init
|
||||
Input* input,
|
||||
Anm2* anm2,
|
||||
Preview* preview,
|
||||
Settings* settings,
|
||||
SDL_Window* window,
|
||||
SDL_GLContext* glContext
|
||||
);
|
||||
|
14
src/input.h
14
src/input.h
@ -9,11 +9,24 @@ enum MouseType
|
||||
MOUSE_RIGHT
|
||||
};
|
||||
|
||||
#define KEY_COUNT (KEY_DELETE + 1)
|
||||
enum KeyType
|
||||
{
|
||||
KEY_DELETE
|
||||
};
|
||||
|
||||
#define INPUT_COUNT (INPUT_MOUSE_CLICK + 1)
|
||||
enum InputType
|
||||
{
|
||||
INPUT_MOUSE_CLICK
|
||||
};
|
||||
|
||||
struct Keyboard
|
||||
{
|
||||
bool current[MOUSE_COUNT];
|
||||
bool previous[MOUSE_COUNT];
|
||||
};
|
||||
|
||||
struct Mouse
|
||||
{
|
||||
bool current[MOUSE_COUNT];
|
||||
@ -26,6 +39,7 @@ struct Mouse
|
||||
|
||||
struct Input
|
||||
{
|
||||
Keyboard keyboard;
|
||||
Mouse mouse;
|
||||
};
|
||||
|
||||
|
349
src/preview.cpp
349
src/preview.cpp
@ -11,7 +11,7 @@ _preview_axis_set(Preview* self)
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(PREVIEW_AXIS_VERTICES), PREVIEW_AXIS_VERTICES, GL_STATIC_DRAW);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(f32), (void*)0);
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
@ -21,13 +21,13 @@ _preview_grid_set(Preview* self)
|
||||
{
|
||||
std::vector<f32> vertices;
|
||||
|
||||
s32 verticalLineCount = PREVIEW_SIZE.x / self->gridSize.x;
|
||||
s32 horizontalLineCount = PREVIEW_SIZE.y / self->gridSize.y;
|
||||
s32 verticalLineCount = PREVIEW_SIZE.x / MIN(self->settings->gridSizeX, PREVIEW_GRID_MIN);
|
||||
s32 horizontalLineCount = PREVIEW_SIZE.y / MIN(self->settings->gridSizeY, PREVIEW_GRID_MIN);
|
||||
|
||||
/* Vertical */
|
||||
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;
|
||||
|
||||
vertices.push_back(normX);
|
||||
@ -39,7 +39,7 @@ _preview_grid_set(Preview* self)
|
||||
/* Horizontal */
|
||||
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;
|
||||
|
||||
vertices.push_back(-1.0f);
|
||||
@ -52,17 +52,19 @@ _preview_grid_set(Preview* self)
|
||||
|
||||
glBindVertexArray(self->gridVAO);
|
||||
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);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(f32), (void*)0);
|
||||
}
|
||||
|
||||
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->input = input;
|
||||
self->settings = settings;
|
||||
|
||||
glGenFramebuffers(1, &self->fbo);
|
||||
|
||||
@ -89,6 +91,28 @@ preview_init(Preview* self, Resources* resources, Input* input)
|
||||
glGenVertexArrays(1, &self->gridVAO);
|
||||
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_grid_set(self);
|
||||
}
|
||||
@ -96,52 +120,74 @@ preview_init(Preview* self, Resources* resources, Input* input)
|
||||
void
|
||||
preview_tick(Preview* self)
|
||||
{
|
||||
self->zoom = CLAMP(self->zoom, PREVIEW_ZOOM_MIN, PREVIEW_ZOOM_MAX);
|
||||
self->oldGridSize = self->gridSize;
|
||||
self->settings->zoom = CLAMP(self->settings->zoom, PREVIEW_ZOOM_MIN, PREVIEW_ZOOM_MAX);
|
||||
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
|
||||
preview_draw(Preview* self)
|
||||
{
|
||||
GLuint shader = self->resources->shaders[SHADER];
|
||||
float zoomFactor = self->zoom / 100.0f;
|
||||
GLuint shaderLine = self->resources->shaders[SHADER_LINE];
|
||||
GLuint shaderTexture = self->resources->shaders[SHADER_TEXTURE];
|
||||
|
||||
f32 zoomFactor = self->settings->zoom / 100.0f;
|
||||
|
||||
/* Convert pan to pixels */
|
||||
glm::vec2 ndcPan = glm::vec2(
|
||||
self->pan.x / (PREVIEW_SIZE.x / 2.0f),
|
||||
-self->pan.y / (PREVIEW_SIZE.y / 2.0f)
|
||||
self->settings->panX / (PREVIEW_SIZE.x / 2.0f),
|
||||
-self->settings->panY / (PREVIEW_SIZE.y / 2.0f)
|
||||
);
|
||||
|
||||
/* Transformation matrix */
|
||||
glm::mat4 transform = glm::translate(glm::mat4(1.0f), glm::vec3(ndcPan, 0.0f));
|
||||
transform = glm::scale(transform, glm::vec3(zoomFactor, zoomFactor, 1.0f));
|
||||
|
||||
glm::mat4 previewTransform = glm::translate(glm::mat4(1.0f), glm::vec3(ndcPan, 0.0f));
|
||||
previewTransform = glm::scale(previewTransform, glm::vec3(zoomFactor, zoomFactor, 1.0f));
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, self->fbo);
|
||||
glViewport(0, 0, PREVIEW_SIZE.x, PREVIEW_SIZE.y);
|
||||
|
||||
glClearColor
|
||||
(
|
||||
self->backgroundColor.r,
|
||||
self->backgroundColor.g,
|
||||
self->backgroundColor.b,
|
||||
self->backgroundColor.a
|
||||
self->settings->backgroundColorR,
|
||||
self->settings->backgroundColorG,
|
||||
self->settings->backgroundColorB,
|
||||
self->settings->backgroundColorA
|
||||
);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glUseProgram(shader);
|
||||
glUniformMatrix4fv(glGetUniformLocation(shader, SHADER_UNIFORM_TRANSFORM), 1, GL_FALSE, (f32*)value_ptr(transform));
|
||||
glUseProgram(shaderLine);
|
||||
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);
|
||||
|
||||
glBindVertexArray(self->gridVAO);
|
||||
|
||||
glUniform4f
|
||||
(
|
||||
glGetUniformLocation(shader, SHADER_UNIFORM_COLOR),
|
||||
self->gridColor.r, self->gridColor.g, self->gridColor.b, self->gridColor.a
|
||||
glGetUniformLocation(shaderLine, SHADER_UNIFORM_COLOR),
|
||||
self->settings->gridColorR, self->settings->gridColorG, self->settings->gridColorB, self->settings->gridColorA
|
||||
);
|
||||
|
||||
glDrawArrays(GL_LINES, 0, self->gridVertexCount);
|
||||
@ -149,31 +195,264 @@ preview_draw(Preview* self)
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
if (self->isAxis)
|
||||
if (self->settings->isAxis)
|
||||
{
|
||||
glBindVertexArray(self->axisVAO);
|
||||
|
||||
/* Axes */
|
||||
glUniform4f
|
||||
(
|
||||
glGetUniformLocation(shader, SHADER_UNIFORM_COLOR),
|
||||
self->axisColor.r, self->axisColor.g, self->axisColor.b, self->axisColor.a
|
||||
glGetUniformLocation(shaderLine, SHADER_UNIFORM_COLOR),
|
||||
self->settings->axisColorR, self->settings->axisColorG, self->settings->axisColorB, self->settings->axisColorA
|
||||
);
|
||||
glDrawArrays(GL_LINES, 0, 2);
|
||||
|
||||
glUniform4f
|
||||
(
|
||||
glGetUniformLocation(shader, SHADER_UNIFORM_COLOR),
|
||||
self->axisColor.r, self->axisColor.g, self->axisColor.b, self->axisColor.a
|
||||
glGetUniformLocation(shaderLine, SHADER_UNIFORM_COLOR),
|
||||
self->settings->axisColorR, self->settings->axisColorG, self->settings->axisColorB, self->settings->axisColorA
|
||||
);
|
||||
glDrawArrays(GL_LINES, 2, 2);
|
||||
|
||||
|
||||
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
|
||||
|
@ -1,16 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "anm2.h"
|
||||
#include "resources.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};
|
||||
|
||||
#define PREVIEW_ZOOM_MIN 1
|
||||
#define PREVIEW_ZOOM_MAX 400
|
||||
#define PREVIEW_ZOOM_MIN 1.0f
|
||||
#define PREVIEW_ZOOM_MAX 800.0f
|
||||
#define PREVIEW_GRID_MIN 1
|
||||
#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[] =
|
||||
{
|
||||
@ -20,31 +25,44 @@ static const f32 PREVIEW_AXIS_VERTICES[] =
|
||||
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
|
||||
{
|
||||
GLuint texture;
|
||||
GLuint fbo;
|
||||
GLuint rbo;
|
||||
GLuint gridVAO;
|
||||
GLuint gridVBO;
|
||||
Anm2* anm2 = NULL;
|
||||
Input* input = NULL;
|
||||
Resources* resources = NULL;
|
||||
Settings* settings = NULL;
|
||||
GLuint axisVAO;
|
||||
GLuint axisVBO;
|
||||
Input* input;
|
||||
Resources* resources;
|
||||
bool isGrid = false;
|
||||
bool isAxis = true;
|
||||
ivec2 viewport = PREVIEW_SIZE;
|
||||
f32 zoom = 100;
|
||||
vec2 pan = PREVIEW_CENTER;
|
||||
ivec2 gridSize = {10, 10};
|
||||
GLuint fbo;
|
||||
GLuint gridVAO;
|
||||
GLuint gridVBO;
|
||||
GLuint rbo;
|
||||
GLuint texture;
|
||||
GLuint textureEBO;
|
||||
GLuint textureVAO;
|
||||
GLuint textureVBO;
|
||||
bool isPlaying = false;
|
||||
f32 time = 0;
|
||||
ivec2 oldGridOffset = {-1, -1};
|
||||
ivec2 oldGridSize = {-1, -1};
|
||||
ivec2 viewport = PREVIEW_SIZE;
|
||||
s32 animationID = -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_tick(Preview* self);
|
||||
void preview_free(Preview* self);
|
||||
|
@ -25,6 +25,7 @@ resources_free(Resources* self)
|
||||
resources_loaded_textures_free(self);
|
||||
}
|
||||
|
||||
/* Frees loaded textures */
|
||||
void
|
||||
resources_loaded_textures_free(Resources* self)
|
||||
{
|
||||
|
161
src/settings.cpp
Normal file
161
src/settings.cpp
Normal 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
115
src/settings.h
Normal 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);
|
@ -29,6 +29,8 @@ _tick(State* state)
|
||||
}
|
||||
}
|
||||
|
||||
SDL_GetWindowSize(state->window, &state->settings.windowW, &state->settings.windowH);
|
||||
|
||||
input_tick(&state->input);
|
||||
preview_tick(&state->preview);
|
||||
dialog_tick(&state->dialog);
|
||||
@ -47,6 +49,15 @@ _draw(State* state)
|
||||
void
|
||||
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);
|
||||
|
||||
if (!SDL_Init(SDL_INIT_VIDEO))
|
||||
@ -60,15 +71,21 @@ init(State* state)
|
||||
SDL_CreateWindowAndRenderer
|
||||
(
|
||||
STRING_WINDOW_TITLE,
|
||||
WINDOW_WIDTH,
|
||||
WINDOW_HEIGHT,
|
||||
state->settings.windowW,
|
||||
state->settings.windowH,
|
||||
WINDOW_FLAGS,
|
||||
&state->window,
|
||||
&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);
|
||||
|
||||
printf(STRING_INFO_OPENGL, glGetString(GL_VERSION));
|
||||
|
||||
if (!state->glContext)
|
||||
{
|
||||
printf(STRING_ERROR_GL_CONTEXT_INIT, SDL_GetError());
|
||||
@ -76,24 +93,18 @@ init(State* state)
|
||||
}
|
||||
|
||||
glewInit();
|
||||
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
printf(STRING_INFO_GLEW_INIT);
|
||||
|
||||
|
||||
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
|
||||
(
|
||||
&state->imgui,
|
||||
@ -102,9 +113,17 @@ init(State* state)
|
||||
&state->input,
|
||||
&state->anm2,
|
||||
&state->preview,
|
||||
&state->settings,
|
||||
state->window,
|
||||
&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
|
||||
@ -129,7 +148,11 @@ loop(State* state)
|
||||
void
|
||||
quit(State* state)
|
||||
{
|
||||
/* return to base path */
|
||||
std::filesystem::current_path(state->startPath);
|
||||
|
||||
imgui_free(&state->imgui);
|
||||
settings_save(&state->settings);
|
||||
preview_free(&state->preview);
|
||||
resources_free(&state->resources);
|
||||
|
||||
|
@ -1,11 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "shader.h"
|
||||
#include "imgui.h"
|
||||
|
||||
#define TICK_DELAY 16
|
||||
#define WINDOW_WIDTH 1600
|
||||
#define WINDOW_HEIGHT 900
|
||||
#define WINDOW_WIDTH 1920
|
||||
#define WINDOW_HEIGHT 1080
|
||||
#define WINDOW_FLAGS SDL_WINDOW_RESIZABLE
|
||||
|
||||
struct State
|
||||
@ -19,7 +17,9 @@ struct State
|
||||
Preview preview;
|
||||
Anm2 anm2;
|
||||
Resources resources;
|
||||
Settings settings;
|
||||
char argument[PATH_MAX] = STRING_EMPTY;
|
||||
char startPath[PATH_MAX] = STRING_EMPTY;
|
||||
bool isArgument = false;
|
||||
u64 tick = 0;
|
||||
u64 lastTick = 0;
|
||||
|
@ -7,6 +7,7 @@ struct Texture
|
||||
GLuint handle = 0;
|
||||
ivec2 size = {0, 0};
|
||||
s32 channels = -1;
|
||||
bool isInvalid = false;
|
||||
};
|
||||
|
||||
void texture_gl_set(Texture* self, void* data);
|
||||
|
Reference in New Issue
Block a user