Added fit, fixed the layer -1 bug finally, refactored here and there
This commit is contained in:
BIN
assets/atlas.png
BIN
assets/atlas.png
Binary file not shown.
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
109
src/COMMON.h
109
src/COMMON.h
@@ -51,15 +51,17 @@ using namespace glm;
|
|||||||
#define FLOAT_TO_U8(x) (static_cast<u8>((x) * 255.0f))
|
#define FLOAT_TO_U8(x) (static_cast<u8>((x) * 255.0f))
|
||||||
#define U8_TO_FLOAT(x) ((x) / 255.0f)
|
#define U8_TO_FLOAT(x) ((x) / 255.0f)
|
||||||
#define PERCENT_TO_UNIT(x) (x / 100.0f)
|
#define PERCENT_TO_UNIT(x) (x / 100.0f)
|
||||||
|
#define UNIT_TO_PERCENT(x) (x * 100.0f)
|
||||||
#define SECOND 1000.0f
|
#define SECOND 1000.0f
|
||||||
#define TICK_DELAY (SECOND / 30.0)
|
#define TICK_DELAY (SECOND / 30.0)
|
||||||
#define UPDATE_DELAY (SECOND / 120.0)
|
#define UPDATE_DELAY (SECOND / 120.0)
|
||||||
#define ID_NONE -1
|
#define ID_NONE -1
|
||||||
#define INDEX_NONE -1
|
#define INDEX_NONE -1
|
||||||
|
#define VALUE_NONE -1
|
||||||
#define TIME_NONE -1.0f
|
#define TIME_NONE -1.0f
|
||||||
#define GL_ID_NONE 0
|
#define GL_ID_NONE 0
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#ifdef _WIN32
|
||||||
#define POPEN _popen
|
#define POPEN _popen
|
||||||
#define PCLOSE _pclose
|
#define PCLOSE _pclose
|
||||||
#define PWRITE_MODE "wb"
|
#define PWRITE_MODE "wb"
|
||||||
@@ -71,7 +73,6 @@ using namespace glm;
|
|||||||
#define PREAD_MODE "r"
|
#define PREAD_MODE "r"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static const GLuint GL_TEXTURE_INDICES[] = {0, 1, 2, 2, 3, 0};
|
static const GLuint GL_TEXTURE_INDICES[] = {0, 1, 2, 2, 3, 0};
|
||||||
static const vec4 COLOR_RED = {1.0f, 0.0f, 0.0f, 1.0f};
|
static const vec4 COLOR_RED = {1.0f, 0.0f, 0.0f, 1.0f};
|
||||||
static const vec4 COLOR_GREEN = {0.0f, 1.0f, 0.0f, 1.0f};
|
static const vec4 COLOR_GREEN = {0.0f, 1.0f, 0.0f, 1.0f};
|
||||||
@@ -104,6 +105,15 @@ static inline std::string string_quote(const std::string& string)
|
|||||||
return "\"" + string + "\"";
|
return "\"" + string + "\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline std::string string_to_lowercase(std::string string) {
|
||||||
|
std::transform
|
||||||
|
(
|
||||||
|
string.begin(), string.end(), string.begin(),
|
||||||
|
[](u8 character){ return std::tolower(character); }
|
||||||
|
);
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
#define FLOAT_FORMAT_MAX_DECIMALS 2
|
#define FLOAT_FORMAT_MAX_DECIMALS 2
|
||||||
#define FLOAT_FORMAT_EPSILON 1e-6f
|
#define FLOAT_FORMAT_EPSILON 1e-6f
|
||||||
static constexpr f32 FLOAT_FORMAT_POW10[] = {1.f, 10.f, 100.f};
|
static constexpr f32 FLOAT_FORMAT_POW10[] = {1.f, 10.f, 100.f};
|
||||||
@@ -144,65 +154,6 @@ static inline const char* vec2_format_get(const vec2& value)
|
|||||||
return formatString.c_str();
|
return formatString.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline std::string path_canonical_resolve
|
|
||||||
(
|
|
||||||
const std::string& inputPath,
|
|
||||||
const std::string& basePath = std::filesystem::current_path().string()
|
|
||||||
)
|
|
||||||
{
|
|
||||||
auto strings_equal_ignore_case = [](std::string a, std::string b) {
|
|
||||||
auto to_lower = [](unsigned char c) { return static_cast<char>(std::tolower(c)); };
|
|
||||||
std::transform(a.begin(), a.end(), a.begin(), to_lower);
|
|
||||||
std::transform(b.begin(), b.end(), b.begin(), to_lower);
|
|
||||||
return a == b;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string sanitized = inputPath;
|
|
||||||
std::replace(sanitized.begin(), sanitized.end(), '\\', '/');
|
|
||||||
|
|
||||||
std::filesystem::path normalizedPath = sanitized;
|
|
||||||
std::filesystem::path absolutePath = normalizedPath.is_absolute()
|
|
||||||
? normalizedPath
|
|
||||||
: (std::filesystem::path(basePath) / normalizedPath);
|
|
||||||
|
|
||||||
std::error_code error;
|
|
||||||
if (std::filesystem::exists(absolutePath, error)) {
|
|
||||||
std::error_code canonicalError;
|
|
||||||
std::filesystem::path canonicalPath = std::filesystem::weakly_canonical(absolutePath, canonicalError);
|
|
||||||
return (canonicalError ? absolutePath : canonicalPath).generic_string();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::filesystem::path resolvedPath = absolutePath.root_path();
|
|
||||||
std::filesystem::path remainingPath = absolutePath.relative_path();
|
|
||||||
|
|
||||||
for (const std::filesystem::path& segment : remainingPath) {
|
|
||||||
std::filesystem::path candidatePath = resolvedPath / segment;
|
|
||||||
if (std::filesystem::exists(candidatePath, error)) {
|
|
||||||
resolvedPath = candidatePath;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool matched = false;
|
|
||||||
if (std::filesystem::exists(resolvedPath, error) && std::filesystem::is_directory(resolvedPath, error)) {
|
|
||||||
for (const auto& directoryEntry : std::filesystem::directory_iterator(resolvedPath, error)) {
|
|
||||||
if (strings_equal_ignore_case(directoryEntry.path().filename().string(), segment.string())) {
|
|
||||||
resolvedPath = directoryEntry.path();
|
|
||||||
matched = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!matched) return sanitized;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!std::filesystem::exists(resolvedPath, error))
|
|
||||||
return sanitized;
|
|
||||||
|
|
||||||
std::error_code canonicalError;
|
|
||||||
std::filesystem::path canonicalPath = std::filesystem::weakly_canonical(resolvedPath, canonicalError);
|
|
||||||
return (canonicalError ? resolvedPath : canonicalPath).generic_string();
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline std::string working_directory_from_file_set(const std::string& path)
|
static inline std::string working_directory_from_file_set(const std::string& path)
|
||||||
{
|
{
|
||||||
std::filesystem::path filePath = path;
|
std::filesystem::path filePath = path;
|
||||||
@@ -237,7 +188,6 @@ static inline bool path_is_valid(const std::filesystem::path& pathCheck)
|
|||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
|
|
||||||
if (fs::is_directory(pathCheck, ec)) return false;
|
if (fs::is_directory(pathCheck, ec)) return false;
|
||||||
if (fs::exists(pathCheck, ec) && !fs::is_regular_file(pathCheck, ec)) return false;
|
|
||||||
|
|
||||||
fs::path parentDir = pathCheck.has_parent_path() ? pathCheck.parent_path() : fs::path(".");
|
fs::path parentDir = pathCheck.has_parent_path() ? pathCheck.parent_path() : fs::path(".");
|
||||||
if (!fs::is_directory(parentDir, ec)) return false;
|
if (!fs::is_directory(parentDir, ec)) return false;
|
||||||
@@ -248,7 +198,7 @@ static inline bool path_is_valid(const std::filesystem::path& pathCheck)
|
|||||||
testStream.close();
|
testStream.close();
|
||||||
|
|
||||||
if (!existedBefore && isValid)
|
if (!existedBefore && isValid)
|
||||||
fs::remove(pathCheck, ec); // cleanup if we created it
|
fs::remove(pathCheck, ec);
|
||||||
|
|
||||||
return isValid;
|
return isValid;
|
||||||
}
|
}
|
||||||
@@ -343,6 +293,39 @@ static inline void map_insert_shift(std::map<int, T>& map, s32 index, const T& v
|
|||||||
map[insertIndex] = value;
|
map[insertIndex] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline mat4 quad_model_get(vec2 size = {}, vec2 position = {}, vec2 pivot = {}, vec2 scale = vec2(1.0f), f32 rotation = {})
|
||||||
|
{
|
||||||
|
vec2 scaleAbsolute = glm::abs(scale);
|
||||||
|
vec2 scaleSign = glm::sign(scale);
|
||||||
|
vec2 pivotScaled = pivot * scaleAbsolute;
|
||||||
|
vec2 sizeScaled = size * scaleAbsolute;
|
||||||
|
|
||||||
|
mat4 model(1.0f);
|
||||||
|
model = glm::translate(model, vec3(position - pivotScaled, 0.0f));
|
||||||
|
model = glm::translate(model, vec3(pivotScaled, 0.0f));
|
||||||
|
model = glm::scale(model, vec3(scaleSign, 1.0f));
|
||||||
|
model = glm::rotate(model, glm::radians(rotation), vec3(0, 0, 1));
|
||||||
|
model = glm::translate(model, vec3(-pivotScaled, 0.0f));
|
||||||
|
model = glm::scale(model, vec3(sizeScaled, 1.0f));
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline mat4 quad_model_parent_get(vec2 position = {}, vec2 pivot = {}, vec2 scale = vec2(1.0f), f32 rotation = {})
|
||||||
|
{
|
||||||
|
vec2 scaleSign = glm::sign(scale);
|
||||||
|
vec2 scaleAbsolute = glm::abs(scale);
|
||||||
|
f32 handedness = (scaleSign.x * scaleSign.y) < 0.0f ? -1.0f : 1.0f;
|
||||||
|
|
||||||
|
mat4 local(1.0f);
|
||||||
|
local = glm::translate(local, vec3(pivot, 0.0f));
|
||||||
|
local = glm::scale(local, vec3(scaleSign, 1.0f));
|
||||||
|
local = glm::rotate(local, glm::radians(rotation) * handedness, vec3(0, 0, 1));
|
||||||
|
local = glm::translate(local, vec3(-pivot, 0.0f));
|
||||||
|
local = glm::scale(local, vec3(scaleAbsolute, 1.0f));
|
||||||
|
|
||||||
|
return glm::translate(mat4(1.0f), vec3(position, 0.0f)) * local;
|
||||||
|
}
|
||||||
|
|
||||||
#define DEFINE_ENUM_TO_STRING_FUNCTION(function, array, count) \
|
#define DEFINE_ENUM_TO_STRING_FUNCTION(function, array, count) \
|
||||||
static inline std::string function(s32 index) \
|
static inline std::string function(s32 index) \
|
||||||
{ \
|
{ \
|
||||||
|
190
src/PACKED.h
190
src/PACKED.h
@@ -8,101 +8,103 @@ const u8 TEXTURE_ATLAS[] =
|
|||||||
{
|
{
|
||||||
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, 0x60, 0x00, 0x00, 0x00, 0xa0,
|
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xa0,
|
||||||
0x02, 0x03, 0x00, 0x00, 0x00, 0x8e, 0x1e, 0x81, 0x1f, 0x00, 0x00, 0x00,
|
0x04, 0x03, 0x00, 0x00, 0x00, 0x01, 0x5e, 0x74, 0xbf, 0x00, 0x00, 0x00,
|
||||||
0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x12, 0x00, 0x00, 0x0b,
|
0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x12, 0x00, 0x00, 0x0b,
|
||||||
0x12, 0x01, 0xd2, 0xdd, 0x7e, 0xfc, 0x00, 0x00, 0x00, 0x0c, 0x50, 0x4c,
|
0x12, 0x01, 0xd2, 0xdd, 0x7e, 0xfc, 0x00, 0x00, 0x00, 0x0f, 0x50, 0x4c,
|
||||||
0x54, 0x45, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60,
|
0x54, 0x45, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x60, 0x60, 0x60, 0xff,
|
||||||
0x60, 0x60, 0x58, 0xe6, 0xdc, 0x65, 0x00, 0x00, 0x00, 0x02, 0x74, 0x52,
|
0xff, 0xff, 0x60, 0x60, 0x60, 0x15, 0x68, 0x14, 0xc2, 0x00, 0x00, 0x00,
|
||||||
0x4e, 0x53, 0x00, 0x00, 0x76, 0x93, 0xcd, 0x38, 0x00, 0x00, 0x04, 0x15,
|
0x03, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x00, 0x00, 0xfa, 0x76, 0xc4, 0xde,
|
||||||
0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xe5, 0xd3, 0xb1, 0x6a, 0x1c, 0x47,
|
0x00, 0x00, 0x04, 0x17, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xed, 0x96,
|
||||||
0x1c, 0xc7, 0xf1, 0x2f, 0xb3, 0xc4, 0x2c, 0xe3, 0x63, 0xaf, 0x4b, 0x91,
|
0x0d, 0x6e, 0xe3, 0x3a, 0x0c, 0x84, 0x07, 0x18, 0x9e, 0xe0, 0xdd, 0xe0,
|
||||||
0x6a, 0x49, 0xb5, 0xcc, 0x1d, 0xf6, 0x81, 0x1b, 0xb1, 0x36, 0x56, 0x1e,
|
0xdd, 0x80, 0xc0, 0xf0, 0x00, 0x04, 0xc4, 0xfb, 0x9f, 0x69, 0x61, 0xc9,
|
||||||
0x21, 0x75, 0xde, 0xc0, 0x79, 0x8a, 0xc1, 0x95, 0x48, 0x61, 0x5c, 0x24,
|
0x82, 0xbc, 0x75, 0xda, 0xd8, 0x1b, 0xb4, 0x01, 0x16, 0x3b, 0x40, 0x2b,
|
||||||
0xfd, 0x20, 0x1c, 0x98, 0xfc, 0x77, 0xd1, 0x2d, 0x49, 0x63, 0x14, 0x81,
|
0xd1, 0xd1, 0x17, 0xfe, 0x88, 0xb2, 0x82, 0x3f, 0x91, 0x84, 0x87, 0xa2,
|
||||||
0xb6, 0x34, 0x41, 0xe4, 0x19, 0x5c, 0x8a, 0xb3, 0x09, 0x02, 0x37, 0xe1,
|
0xa3, 0xab, 0x45, 0x5f, 0x75, 0x58, 0x2f, 0xf5, 0x21, 0x29, 0xe5, 0x61,
|
||||||
0x72, 0xf8, 0x92, 0x19, 0x5d, 0xb4, 0x91, 0x6e, 0x94, 0x20, 0xab, 0x48,
|
0xbd, 0xe4, 0x87, 0x2f, 0x54, 0x05, 0x60, 0xfd, 0x39, 0x20, 0x07, 0x3b,
|
||||||
0xe1, 0x1f, 0x0c, 0x03, 0xf7, 0xe1, 0xfe, 0x33, 0xf3, 0xdf, 0x19, 0xae,
|
0x39, 0x96, 0x34, 0x49, 0x60, 0x37, 0x17, 0x50, 0x14, 0xc0, 0xdd, 0x95,
|
||||||
0x8f, 0x76, 0x5c, 0x44, 0x59, 0x28, 0x3a, 0x34, 0x00, 0x22, 0xe8, 0xd6,
|
0xd4, 0xa7, 0x6b, 0x85, 0x44, 0x75, 0xf9, 0x0a, 0x89, 0x0a, 0xd3, 0x00,
|
||||||
0xb4, 0x00, 0x18, 0x0f, 0xda, 0xa1, 0xff, 0x60, 0x86, 0x72, 0xda, 0x96,
|
0x28, 0xe1, 0xb0, 0xc0, 0x1c, 0x38, 0xda, 0xf4, 0x1d, 0x90, 0x34, 0x2c,
|
||||||
0x5a, 0x3c, 0x2c, 0x44, 0x89, 0xd8, 0x00, 0x63, 0x43, 0x89, 0x46, 0xbb,
|
0x39, 0x9d, 0x3d, 0x7a, 0x5b, 0x0b, 0x56, 0x48, 0x27, 0x80, 0x02, 0x9d,
|
||||||
0x92, 0x00, 0x22, 0x46, 0xc4, 0xc7, 0x52, 0xe6, 0x27, 0x87, 0xc6, 0xb8,
|
0xe8, 0x72, 0xfa, 0x58, 0x60, 0xd5, 0xa4, 0xa8, 0xfc, 0x1d, 0x88, 0x6e,
|
||||||
0xf8, 0x43, 0x66, 0x89, 0xb3, 0xb2, 0x68, 0x23, 0x8e, 0x0a, 0x5f, 0x4d,
|
0xc9, 0x8f, 0x40, 0xa0, 0x65, 0x07, 0xaa, 0x45, 0x6d, 0x80, 0x8d, 0xda,
|
||||||
0x61, 0x07, 0x65, 0x09, 0xa5, 0x06, 0x50, 0xae, 0x2a, 0x21, 0xaf, 0x94,
|
0xa9, 0x65, 0xf7, 0x48, 0xa7, 0x70, 0x00, 0x4c, 0x10, 0x30, 0x88, 0xbe,
|
||||||
0x65, 0x77, 0xd1, 0xac, 0x36, 0xd0, 0x51, 0x69, 0x1b, 0x61, 0x52, 0xf4,
|
0x1e, 0xcd, 0x19, 0x00, 0x34, 0xb3, 0xef, 0x98, 0x30, 0x01, 0x4c, 0x20,
|
||||||
0xec, 0xbe, 0x3f, 0x5e, 0x51, 0xb7, 0xe8, 0xb7, 0x62, 0xa9, 0x0c, 0x11,
|
0xb7, 0xf5, 0x99, 0x26, 0x01, 0x52, 0x42, 0xc7, 0x7d, 0x3e, 0x02, 0x4d,
|
||||||
0x6a, 0x0d, 0xd9, 0x7a, 0xdd, 0x73, 0x3a, 0x41, 0xf3, 0x06, 0xb4, 0xc7,
|
0xd1, 0x1d, 0x98, 0x59, 0x99, 0x81, 0x3d, 0x0c, 0xf9, 0x04, 0xd6, 0xc6,
|
||||||
0x05, 0xd0, 0x1a, 0x46, 0xeb, 0xd5, 0x49, 0xed, 0x74, 0xab, 0x37, 0x07,
|
0xcd, 0x2a, 0x51, 0x8e, 0xae, 0xdc, 0x74, 0x06, 0x66, 0x6b, 0x98, 0xba,
|
||||||
0x8f, 0x50, 0x34, 0xf0, 0xe0, 0xc1, 0xbb, 0x99, 0xb1, 0xca, 0x07, 0x88,
|
0x72, 0x35, 0x8d, 0x99, 0x01, 0x30, 0xe5, 0xf8, 0xa7, 0xe7, 0xcd, 0x87,
|
||||||
0x07, 0x0c, 0xbb, 0x52, 0x1e, 0x38, 0x39, 0xe9, 0x2f, 0x00, 0x11, 0x6a,
|
0xc4, 0x0f, 0x89, 0x8e, 0x87, 0x32, 0x29, 0x4f, 0xf6, 0x67, 0x21, 0xaf,
|
||||||
0x91, 0x16, 0x07, 0x3c, 0x98, 0x51, 0xf7, 0x59, 0xab, 0xb7, 0x9a, 0x48,
|
0xe4, 0xd1, 0x34, 0x5a, 0xa0, 0x24, 0xa9, 0xe6, 0xb9, 0x38, 0x6b, 0x96,
|
||||||
0xcf, 0x6d, 0x53, 0xb7, 0xc3, 0x7c, 0x29, 0x22, 0x14, 0x22, 0xdd, 0x58,
|
0x17, 0x81, 0x8d, 0xda, 0x40, 0x40, 0xf1, 0x45, 0x28, 0xaa, 0x2a, 0x09,
|
||||||
0xe4, 0x0c, 0x86, 0xc4, 0x2d, 0xdf, 0x85, 0xd7, 0x85, 0xd3, 0xdd, 0xa5,
|
0xf0, 0x4e, 0x03, 0xca, 0x4f, 0x82, 0xb1, 0x51, 0x7e, 0x53, 0x55, 0x93,
|
||||||
0x32, 0x7a, 0xbd, 0x74, 0x39, 0x94, 0xba, 0x1f, 0xb6, 0x48, 0x26, 0xd2,
|
0x72, 0x02, 0x26, 0x80, 0xc3, 0xa6, 0x83, 0x58, 0x62, 0x54, 0x35, 0xef,
|
||||||
0xd7, 0xeb, 0x45, 0x1b, 0xa0, 0xc6, 0xb4, 0x43, 0x99, 0xe3, 0xf7, 0x76,
|
0x83, 0xa2, 0xf9, 0x0e, 0xac, 0x73, 0xe2, 0xff, 0xd1, 0xff, 0xa7, 0x2f,
|
||||||
0xb2, 0x6e, 0x4e, 0x03, 0x84, 0x6f, 0x73, 0x01, 0x0f, 0x7f, 0xfb, 0xf9,
|
0x07, 0xd1, 0x5a, 0x44, 0x4b, 0x46, 0x35, 0x55, 0xf3, 0xf9, 0x8d, 0xf3,
|
||||||
0xed, 0xe4, 0xfd, 0xfc, 0x34, 0x57, 0xb6, 0xac, 0x94, 0x1b, 0xa0, 0xfd,
|
0x9c, 0xc8, 0x29, 0x39, 0x85, 0x29, 0x25, 0xe9, 0x6e, 0x6a, 0x5e, 0x8a,
|
||||||
0x7c, 0xaf, 0x3e, 0x5d, 0x1e, 0x4f, 0xfe, 0x82, 0x59, 0xa5, 0xed, 0x00,
|
0x62, 0x0c, 0xc0, 0xe6, 0x39, 0x39, 0x03, 0xe6, 0xcc, 0xed, 0x8f, 0x41,
|
||||||
0x3b, 0xd3, 0x9d, 0xe9, 0xc4, 0x10, 0x4a, 0x51, 0x19, 0x06, 0x50, 0xda,
|
0x01, 0x33, 0xa4, 0x75, 0x4e, 0x4e, 0x21, 0x81, 0x90, 0xe0, 0x30, 0x29,
|
||||||
0xd9, 0xba, 0x59, 0xb7, 0x39, 0xda, 0xd5, 0x7e, 0x3c, 0x2c, 0x9e, 0x75,
|
0xaa, 0xf6, 0xa4, 0xa5, 0xcd, 0x76, 0xd4, 0xa3, 0xa4, 0x2d, 0x80, 0x96,
|
||||||
0x45, 0xaf, 0xe7, 0x6b, 0x97, 0x73, 0xef, 0xa5, 0x76, 0xbb, 0x03, 0xb0,
|
0x80, 0x54, 0x55, 0xa3, 0xac, 0x6c, 0xe1, 0x1d, 0xda, 0x80, 0xb3, 0x9a,
|
||||||
0x68, 0x50, 0xf3, 0xa5, 0xbd, 0xcb, 0x8f, 0xcf, 0x0a, 0xb7, 0x3c, 0xde,
|
0x14, 0x00, 0xa8, 0xaa, 0x7d, 0xe3, 0x82, 0xde, 0xd0, 0x84, 0x52, 0x14,
|
||||||
0x6e, 0x49, 0x3b, 0xdd, 0x19, 0x8b, 0x8c, 0x12, 0x4d, 0xd4, 0x8e, 0x7a,
|
0x4e, 0x3a, 0xb7, 0x46, 0x32, 0xcd, 0x51, 0xdd, 0xce, 0xd1, 0x1a, 0xcf,
|
||||||
0x7e, 0xc6, 0x7f, 0x47, 0xd9, 0x30, 0x92, 0xef, 0x23, 0x8c, 0x58, 0x4e,
|
0x9a, 0x4f, 0x1a, 0x76, 0xd5, 0xb0, 0x5e, 0x6d, 0x6f, 0xfa, 0x1a, 0x2f,
|
||||||
0x7d, 0x53, 0xb9, 0x30, 0x80, 0x15, 0x18, 0x4f, 0x1c, 0x22, 0x94, 0x10,
|
0x49, 0x5a, 0xe3, 0x0a, 0x8d, 0x2e, 0xba, 0xd6, 0xd8, 0x55, 0xb9, 0xfa,
|
||||||
0x07, 0x64, 0x2b, 0x62, 0x36, 0x17, 0xba, 0x54, 0xb2, 0x57, 0x42, 0x0e,
|
0xbd, 0x8f, 0x2b, 0x79, 0x62, 0x88, 0x38, 0xc8, 0x2a, 0x31, 0xf5, 0xf1,
|
||||||
0xd3, 0x55, 0x28, 0x11, 0x41, 0xb7, 0xb5, 0x03, 0xd9, 0x23, 0xc2, 0xe1,
|
0x25, 0xcc, 0x3e, 0x73, 0xdf, 0x81, 0xf1, 0x51, 0x56, 0xce, 0x10, 0x16,
|
||||||
0x8c, 0xfc, 0xed, 0xc3, 0x32, 0x74, 0x36, 0x5c, 0xb4, 0x92, 0x85, 0x2d,
|
0x20, 0xa5, 0xed, 0xc1, 0x6d, 0x00, 0x0e, 0x40, 0xc8, 0x00, 0x78, 0x4b,
|
||||||
0x01, 0xd4, 0xa2, 0xa7, 0xea, 0x8a, 0xaa, 0x2a, 0xba, 0xca, 0xf4, 0xf8,
|
0x0b, 0x62, 0xb6, 0xc0, 0x7c, 0x71, 0x11, 0x40, 0x1b, 0x9e, 0xa6, 0xd8,
|
||||||
0x92, 0x4d, 0xa9, 0xbb, 0x8d, 0xc5, 0x3f, 0x7d, 0x6a, 0x44, 0x44, 0x0c,
|
0x94, 0x00, 0x3d, 0x80, 0x46, 0xa7, 0xa3, 0x05, 0xe8, 0xec, 0xee, 0x06,
|
||||||
0x78, 0xd4, 0x41, 0x2c, 0xc5, 0xbd, 0x03, 0x18, 0xc0, 0xfa, 0x52, 0xdb,
|
0xf0, 0x21, 0xa4, 0x50, 0x38, 0x20, 0x77, 0x3a, 0xa9, 0x29, 0x0a, 0x1d,
|
||||||
0x58, 0x8a, 0xc3, 0x97, 0x30, 0x94, 0xda, 0xf7, 0x46, 0xc8, 0x4b, 0xd4,
|
0x00, 0x40, 0xb5, 0x63, 0x48, 0x6c, 0x6a, 0x78, 0x0c, 0x38, 0xe4, 0xec,
|
||||||
0x1e, 0x8b, 0xd7, 0x5c, 0x2c, 0x5e, 0x5b, 0x69, 0x8d, 0x27, 0x07, 0x65,
|
0xd4, 0x0a, 0x69, 0x3a, 0x78, 0x18, 0x92, 0x28, 0xe7, 0xe8, 0x2c, 0xef,
|
||||||
0xd5, 0xc4, 0x32, 0x6c, 0xd7, 0x8b, 0x33, 0x1e, 0x4a, 0x8c, 0xd7, 0xcf,
|
0x00, 0xdd, 0x81, 0xee, 0xe0, 0x9c, 0xb4, 0xc9, 0x21, 0x29, 0xf7, 0x5d,
|
||||||
0x60, 0x38, 0xa0, 0x17, 0x1b, 0xfe, 0x11, 0xc1, 0xc1, 0xd0, 0x92, 0xf0,
|
0x71, 0xcc, 0xfa, 0x91, 0x31, 0x8c, 0x73, 0x59, 0x5d, 0xd2, 0xda, 0xce,
|
||||||
0x8f, 0x4d, 0xa9, 0xc7, 0x16, 0x86, 0x26, 0x22, 0xde, 0xf8, 0x7d, 0xab,
|
0xb9, 0xa5, 0xf2, 0xf6, 0xb8, 0xc9, 0xb8, 0x01, 0x3e, 0x01, 0x5f, 0x80,
|
||||||
0xab, 0x7d, 0xfb, 0x28, 0xd1, 0xf6, 0x9b, 0xc4, 0x02, 0x28, 0x20, 0x73,
|
0xd0, 0x75, 0x6e, 0x8d, 0xe5, 0xe1, 0x18, 0x92, 0x35, 0x7f, 0xd4, 0x7c,
|
||||||
0xc0, 0x08, 0x78, 0x04, 0xea, 0xd7, 0x4e, 0x9d, 0x83, 0x85, 0x79, 0x80,
|
0x73, 0x22, 0xdf, 0x00, 0xd1, 0x01, 0xb1, 0x8f, 0x96, 0x2f, 0xb4, 0xf7,
|
||||||
0x57, 0xc0, 0x12, 0xb2, 0x43, 0xa7, 0xcf, 0xc1, 0x31, 0x69, 0xa1, 0xee,
|
0xab, 0xf2, 0x35, 0x25, 0x86, 0x4c, 0xd8, 0x95, 0xc3, 0x1e, 0x03, 0xb3,
|
||||||
0x3c, 0x64, 0x0b, 0x0b, 0x0b, 0x67, 0x44, 0xfa, 0x4c, 0xc4, 0xeb, 0x37,
|
0x05, 0x40, 0x3f, 0x05, 0xab, 0x9a, 0x40, 0x8e, 0x07, 0xbb, 0x6d, 0x21,
|
||||||
0x90, 0xf9, 0xa9, 0x87, 0xb1, 0x74, 0x28, 0xdd, 0x89, 0x88, 0xd3, 0x22,
|
0x01, 0x3a, 0x02, 0x02, 0xc0, 0x50, 0x0e, 0x37, 0xb1, 0x7f, 0x68, 0x6d,
|
||||||
0xa2, 0x7b, 0x28, 0x7e, 0xbf, 0xdf, 0xc2, 0x63, 0x39, 0x23, 0x57, 0xbd,
|
0x8c, 0x68, 0x12, 0xa8, 0x4d, 0x39, 0xef, 0x61, 0x87, 0x5a, 0xec, 0x61,
|
||||||
0x39, 0x07, 0x3f, 0x9e, 0xcf, 0x5d, 0xbd, 0x9c, 0xf7, 0xf0, 0x4b, 0xd3,
|
0x39, 0x53, 0x3e, 0x1c, 0x28, 0x46, 0xc4, 0x0a, 0x68, 0x08, 0x98, 0x13,
|
||||||
0x53, 0x66, 0x9d, 0xb6, 0x9c, 0x4e, 0x50, 0x2e, 0x80, 0x91, 0x03, 0x4b,
|
0x25, 0xba, 0x5a, 0x39, 0x4b, 0x39, 0x1c, 0xa8, 0x46, 0xb6, 0x4c, 0xf0,
|
||||||
0xb6, 0x3f, 0x07, 0xfb, 0xea, 0xb5, 0xb2, 0x54, 0x15, 0xca, 0x8e, 0x60,
|
0x77, 0xc0, 0x51, 0x2a, 0x95, 0x60, 0x2a, 0xa9, 0x3a, 0x9c, 0x52, 0xe4,
|
||||||
0x56, 0xca, 0x01, 0x14, 0xfe, 0x08, 0x45, 0x09, 0xe7, 0xc0, 0x78, 0xbd,
|
0x28, 0x89, 0x05, 0x20, 0x5f, 0xbf, 0x60, 0x28, 0x4c, 0x80, 0x92, 0xd4,
|
||||||
0x3e, 0x2b, 0xe5, 0x10, 0x6a, 0x99, 0x91, 0x8f, 0x2c, 0x10, 0x00, 0x46,
|
0xbc, 0xc7, 0xc6, 0xe9, 0x20, 0xbd, 0xed, 0x95, 0xa1, 0xef, 0x03, 0x30,
|
||||||
0xcc, 0x66, 0x66, 0x7e, 0x08, 0x5a, 0x7a, 0x72, 0x05, 0x10, 0xd6, 0x20,
|
0x12, 0x06, 0xb1, 0x01, 0x23, 0x53, 0x9f, 0x0e, 0x88, 0x4d, 0x47, 0x00,
|
||||||
0x42, 0x75, 0xff, 0x25, 0x28, 0x81, 0x3c, 0x07, 0x54, 0xd8, 0x95, 0x8d,
|
0x40, 0x75, 0x75, 0x20, 0x84, 0x51, 0x0c, 0x9b, 0x0e, 0x30, 0x34, 0x80,
|
||||||
0x80, 0x39, 0x05, 0x9a, 0x77, 0xa3, 0xc2, 0x0d, 0x10, 0xd6, 0xa0, 0x0e,
|
0xb5, 0x55, 0x06, 0x03, 0xa5, 0xea, 0x00, 0x24, 0xe5, 0x00, 0x88, 0xa1,
|
||||||
0xb0, 0x7b, 0xd2, 0x43, 0x80, 0x70, 0x72, 0xcb, 0x87, 0x45, 0x59, 0x00,
|
0x95, 0xc3, 0x11, 0x70, 0x56, 0xcc, 0xae, 0xc6, 0x00, 0x1c, 0x43, 0x9c,
|
||||||
0x76, 0x12, 0x10, 0xa9, 0x45, 0x5b, 0x50, 0xad, 0xe9, 0xd1, 0x1d, 0x03,
|
0x55, 0xf2, 0x05, 0xf4, 0xc7, 0x7b, 0x87, 0x2b, 0xca, 0x90, 0x68, 0xc2,
|
||||||
0x28, 0x87, 0xf6, 0x57, 0xc1, 0x78, 0xd0, 0x16, 0x2d, 0x36, 0x01, 0x06,
|
0x19, 0x58, 0x39, 0x00, 0x36, 0x01, 0xab, 0xcc, 0xc4, 0x41, 0x9c, 0x3b,
|
||||||
0xb4, 0xf8, 0x01, 0x36, 0x04, 0x4d, 0x8f, 0x16, 0xb1, 0x01, 0xb4, 0x48,
|
0xed, 0xf8, 0x51, 0xd1, 0xd7, 0xdc, 0xfc, 0x12, 0xb0, 0x20, 0x25, 0x56,
|
||||||
0x17, 0x46, 0x5c, 0x23, 0x13, 0x09, 0xd0, 0x5e, 0x06, 0x40, 0x49, 0x13,
|
0x5b, 0x53, 0x49, 0xe5, 0xa8, 0xc6, 0x27, 0x00, 0xf7, 0xfd, 0xf0, 0x67,
|
||||||
0xe0, 0xe8, 0x9f, 0x40, 0xcc, 0xd8, 0xa3, 0xa5, 0xe9, 0x03, 0x8c, 0x97,
|
0xc0, 0x7a, 0xaf, 0x0c, 0x40, 0x7e, 0x0d, 0xa0, 0xb0, 0x03, 0xf2, 0x2f,
|
||||||
0xc7, 0x67, 0xa1, 0x57, 0xf1, 0x5a, 0xc7, 0xed, 0xca, 0xd1, 0xa5, 0xc5,
|
0x80, 0x95, 0xb8, 0x22, 0x27, 0x20, 0x5f, 0x40, 0xb7, 0x63, 0x8e, 0x2b,
|
||||||
0x8d, 0xff, 0x7b, 0xbb, 0x4d, 0x9f, 0x80, 0x1a, 0xf4, 0x11, 0x09, 0x98,
|
0x87, 0x71, 0x14, 0x27, 0xa0, 0xfc, 0x0a, 0x58, 0x8d, 0x10, 0x13, 0x88,
|
||||||
0xc2, 0xb8, 0x87, 0x6c, 0xb5, 0xdb, 0x33, 0x3e, 0x1b, 0x20, 0x95, 0xb8,
|
0x4f, 0x81, 0xa3, 0x4a, 0xbe, 0x03, 0x91, 0x2b, 0xa4, 0x2a, 0x45, 0xd5,
|
||||||
0xf8, 0xb5, 0x59, 0x6f, 0xd2, 0x43, 0x8c, 0x72, 0x0c, 0x10, 0x96, 0xd8,
|
0xec, 0xa5, 0xf5, 0x42, 0x3e, 0x94, 0x55, 0x91, 0x9f, 0x26, 0xdd, 0x81,
|
||||||
0x82, 0x85, 0x48, 0xf3, 0x61, 0xc0, 0xc7, 0x02, 0x46, 0xd2, 0xa0, 0x44,
|
0x8f, 0x65, 0x8d, 0xc4, 0x25, 0xc0, 0x84, 0x59, 0xac, 0x6b, 0x00, 0xc7,
|
||||||
0x5c, 0x12, 0xf4, 0x53, 0xe7, 0xd3, 0xa0, 0x5c, 0x95, 0x84, 0x4a, 0x39,
|
0xc2, 0x4a, 0xcc, 0x6e, 0xb7, 0x31, 0xaf, 0x7a, 0x04, 0x5c, 0xd4, 0x4a,
|
||||||
0x7d, 0x03, 0x90, 0x8b, 0xdc, 0x1c, 0x6e, 0xb3, 0x78, 0xfa, 0x1c, 0xe9,
|
0xfa, 0xb6, 0xea, 0x83, 0xf2, 0xfc, 0xd5, 0x8f, 0x81, 0x99, 0xc1, 0x53,
|
||||||
0x93, 0xa7, 0x7b, 0x95, 0xee, 0xee, 0xff, 0xff, 0xcd, 0x6b, 0x91, 0x36,
|
0xa0, 0xa9, 0x2b, 0x7e, 0x0e, 0xc0, 0x3f, 0xe0, 0xef, 0x00, 0x28, 0xe9,
|
||||||
0x09, 0x85, 0x48, 0x97, 0x84, 0x4c, 0xa4, 0x4f, 0xbe, 0x0f, 0x16, 0x0d,
|
0x0e, 0x40, 0x6d, 0xba, 0x01, 0xc8, 0x29, 0xc8, 0x6f, 0x00, 0xa0, 0xc0,
|
||||||
0x69, 0xa8, 0x5b, 0xd2, 0x50, 0x74, 0x49, 0x88, 0x3f, 0x6d, 0x3d, 0xe7,
|
0xeb, 0x00, 0x1d, 0x14, 0xa0, 0xef, 0x00, 0xf4, 0x40, 0xdf, 0x0f, 0xbc,
|
||||||
0x54, 0x44, 0x48, 0xc6, 0x88, 0xfc, 0x40, 0x22, 0x9f, 0x0a, 0x88, 0x4d,
|
0x21, 0xe9, 0x97, 0xf7, 0x61, 0xed, 0xf4, 0xf7, 0xf4, 0xd2, 0x22, 0xfe,
|
||||||
0xc0, 0xd7, 0x16, 0x94, 0x67, 0x2b, 0x9f, 0xc4, 0x32, 0x26, 0x51, 0xe9,
|
0x9d, 0x69, 0x53, 0x57, 0x5e, 0x02, 0x96, 0x8b, 0xc0, 0x25, 0x60, 0xb9,
|
||||||
0x3b, 0x80, 0x3b, 0xcf, 0xb7, 0xe0, 0xab, 0x2f, 0x01, 0x78, 0xb1, 0x05,
|
0x48, 0x5c, 0xb9, 0x1f, 0x96, 0x8b, 0xc0, 0x1d, 0xc0, 0xa4, 0xbc, 0x05,
|
||||||
0x4f, 0xbe, 0x00, 0xa0, 0xda, 0x82, 0xef, 0x89, 0xd1, 0x5c, 0xc9, 0x9d,
|
0xa0, 0x05, 0x2e, 0x03, 0x6b, 0xd1, 0x93, 0x6b, 0xf7, 0xba, 0x24, 0xdd,
|
||||||
0x6f, 0x37, 0xb3, 0xbd, 0x0a, 0x9b, 0x55, 0xd5, 0x55, 0xf8, 0x8c, 0x4d,
|
0x21, 0xa8, 0x2e, 0xbf, 0xb1, 0x1e, 0x00, 0x2e, 0x13, 0x94, 0xaf, 0xc9,
|
||||||
0x5c, 0x02, 0x92, 0xdb, 0x7a, 0xc2, 0x26, 0xd5, 0x6d, 0x61, 0x28, 0xad,
|
0x15, 0xc9, 0xef, 0x65, 0x4e, 0x3f, 0xcd, 0xbf, 0x96, 0x4e, 0xc6, 0x73,
|
||||||
0x6f, 0x0d, 0x0e, 0x50, 0xf6, 0xa6, 0x00, 0xb7, 0x82, 0xad, 0x73, 0x55,
|
0x07, 0xb7, 0x5c, 0xe8, 0x64, 0xde, 0x71, 0x70, 0xb6, 0x5f, 0x07, 0xf4,
|
||||||
0xb7, 0x85, 0xeb, 0xdb, 0xae, 0xaf, 0xfb, 0x50, 0xca, 0x0e, 0xf3, 0x65,
|
0xe4, 0xc1, 0xcb, 0x00, 0xfd, 0xfc, 0xe4, 0xcd, 0x80, 0x9e, 0x3c, 0x7a,
|
||||||
0x78, 0x4e, 0xfa, 0x32, 0xe0, 0xd2, 0xc7, 0x80, 0x6a, 0x98, 0x92, 0xdb,
|
0x27, 0x40, 0xff, 0x4e, 0xe0, 0xfd, 0x49, 0xbf, 0xbf, 0x35, 0xbe, 0xfd,
|
||||||
0x7a, 0x01, 0x89, 0x8b, 0x95, 0xbc, 0xd4, 0x78, 0xd2, 0xcf, 0x00, 0x93,
|
0x3c, 0xbc, 0xfd, 0x4c, 0x43, 0x27, 0xf3, 0xf6, 0x8b, 0xec, 0x96, 0x0b,
|
||||||
0x7e, 0x38, 0xa0, 0x86, 0xa7, 0x96, 0x78, 0x9c, 0xff, 0xfe, 0x9c, 0xff,
|
0xdd, 0x7f, 0x19, 0xdf, 0x7f, 0xdd, 0xbf, 0x7e, 0xa1, 0xbc, 0x7e, 0x65,
|
||||||
0x04, 0xe2, 0xd8, 0x90, 0xc1, 0x18, 0xe1, 0xf4, 0x9b, 0x00, 0x00, 0x00,
|
0xad, 0x4b, 0xf1, 0x85, 0x6b, 0xf7, 0x17, 0x03, 0x7b, 0x85, 0x59, 0xd8,
|
||||||
0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
|
0xe0, 0xeb, 0xee, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae,
|
||||||
|
0x42, 0x60, 0x82
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const u32 TEXTURE_ATLAS_LENGTH = (u32)std::size(TEXTURE_ATLAS);
|
const u32 TEXTURE_ATLAS_LENGTH = (u32)std::size(TEXTURE_ATLAS);
|
||||||
|
87
src/anm2.cpp
87
src/anm2.cpp
@@ -305,7 +305,7 @@ bool anm2_serialize(Anm2* self, const std::string& path)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool anm2_deserialize(Anm2* self, const std::string& path)
|
bool anm2_deserialize(Anm2* self, const std::string& path, bool isTextures)
|
||||||
{
|
{
|
||||||
XMLDocument xmlDocument;
|
XMLDocument xmlDocument;
|
||||||
XMLError xmlError;
|
XMLError xmlError;
|
||||||
@@ -330,7 +330,13 @@ bool anm2_deserialize(Anm2* self, const std::string& path)
|
|||||||
bool isFirstAnimationDone = false;
|
bool isFirstAnimationDone = false;
|
||||||
std::string defaultAnimation{};
|
std::string defaultAnimation{};
|
||||||
|
|
||||||
if (!self || path.empty()) return false;
|
if (!self) return false;
|
||||||
|
|
||||||
|
if (path.empty())
|
||||||
|
{
|
||||||
|
log_error(ANM2_EMPTY_ERROR);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
anm2_new(self);
|
anm2_new(self);
|
||||||
|
|
||||||
@@ -338,7 +344,7 @@ bool anm2_deserialize(Anm2* self, const std::string& path)
|
|||||||
|
|
||||||
if (xmlError != XML_SUCCESS)
|
if (xmlError != XML_SUCCESS)
|
||||||
{
|
{
|
||||||
log_error(std::format(ANM2_READ_ERROR, xmlDocument.ErrorStr()));
|
log_error(std::format(ANM2_PARSE_ERROR, path, xmlDocument.ErrorStr()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -590,8 +596,17 @@ bool anm2_deserialize(Anm2* self, const std::string& path)
|
|||||||
xmlAttribute = xmlAttribute->Next();
|
xmlAttribute = xmlAttribute->Next();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (anm2Element == ANM2_ELEMENT_SPRITESHEET)
|
if (anm2Element == ANM2_ELEMENT_SPRITESHEET && isTextures)
|
||||||
|
{
|
||||||
|
// Spritesheet paths from Isaac Rebirth are made with the assumption that the paths are case-insensitive (developed on Windows)
|
||||||
|
// However when using the resource dumper, the spritesheet paths are all lowercase (on Linux anyways)
|
||||||
|
// If the check doesn't work, set the spritesheet path to lowercase
|
||||||
|
// If it doesn't work beyond that then that's on the user :^)
|
||||||
|
|
||||||
|
if (!path_exists(spritesheet->path))
|
||||||
|
spritesheet->path = string_to_lowercase(spritesheet->path);
|
||||||
texture_from_path_init(&spritesheet->texture, spritesheet->path);
|
texture_from_path_init(&spritesheet->texture, spritesheet->path);
|
||||||
|
}
|
||||||
|
|
||||||
xmlChild = xmlElement->FirstChildElement();
|
xmlChild = xmlElement->FirstChildElement();
|
||||||
|
|
||||||
@@ -617,20 +632,16 @@ bool anm2_deserialize(Anm2* self, const std::string& path)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set default animation ID
|
|
||||||
for (auto& [id, animation] : self->animations)
|
for (auto& [id, animation] : self->animations)
|
||||||
if (animation.name == defaultAnimation)
|
if (animation.name == defaultAnimation)
|
||||||
self->defaultAnimationID = id;
|
self->defaultAnimationID = id;
|
||||||
|
|
||||||
// Copy texture data to pixels (used for snapshots)
|
if (isTextures) anm2_spritesheet_texture_pixels_download(self);
|
||||||
anm2_spritesheet_texture_pixels_download(self);
|
|
||||||
|
|
||||||
// Read
|
|
||||||
log_info(std::format(ANM2_READ_INFO, path));
|
|
||||||
|
|
||||||
// Return to old working directory
|
|
||||||
std::filesystem::current_path(workingPath);
|
std::filesystem::current_path(workingPath);
|
||||||
|
|
||||||
|
log_info(std::format(ANM2_READ_INFO, path));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1189,9 +1200,61 @@ void anm2_spritesheet_texture_pixels_download(Anm2* self)
|
|||||||
|
|
||||||
if (texture.id != GL_ID_NONE && !texture.isInvalid)
|
if (texture.id != GL_ID_NONE && !texture.isInvalid)
|
||||||
{
|
{
|
||||||
spritesheet.pixels.resize(texture.size.x * texture.size.y * texture.channels);
|
size_t bufferSize = (size_t)texture.size.x * (size_t)texture.size.y * (size_t)texture.channels;
|
||||||
|
spritesheet.pixels.resize(bufferSize);
|
||||||
glBindTexture(GL_TEXTURE_2D, texture.id);
|
glBindTexture(GL_TEXTURE_2D, texture.id);
|
||||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, spritesheet.pixels.data());
|
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, spritesheet.pixels.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec4 anm2_animation_rect_get(Anm2* self, Anm2Reference* reference, bool isRootTransform)
|
||||||
|
{
|
||||||
|
f32 minX = std::numeric_limits<f32>::infinity();
|
||||||
|
f32 minY = std::numeric_limits<f32>::infinity();
|
||||||
|
f32 maxX = -std::numeric_limits<f32>::infinity();
|
||||||
|
f32 maxY = -std::numeric_limits<f32>::infinity();
|
||||||
|
|
||||||
|
bool any = false;
|
||||||
|
|
||||||
|
Anm2Frame frame;
|
||||||
|
Anm2Frame root;
|
||||||
|
|
||||||
|
Anm2Animation* animation = anm2_animation_from_reference(self, reference);
|
||||||
|
if (!animation) return vec4(-1.0f);
|
||||||
|
|
||||||
|
for (f32 t = 0.0f; t <= animation->frameNum; t += 1.0f)
|
||||||
|
{
|
||||||
|
for (const auto& [id, _] : animation->layerAnimations)
|
||||||
|
{
|
||||||
|
anm2_frame_from_time(self, &frame, {reference->animationID, ANM2_LAYER, id}, t);
|
||||||
|
if (!frame.isVisible) continue;
|
||||||
|
if (frame.size.x <= 0 || frame.size.y <= 0) continue;
|
||||||
|
|
||||||
|
mat4 rootModel(1.0f);
|
||||||
|
if (isRootTransform)
|
||||||
|
{
|
||||||
|
anm2_frame_from_time(self, &root, {reference->animationID, ANM2_ROOT}, t);
|
||||||
|
rootModel = quad_model_parent_get(root.position, root.pivot, PERCENT_TO_UNIT(root.scale), root.rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 model = quad_model_get(frame.size, frame.position, frame.pivot, PERCENT_TO_UNIT(frame.scale), frame.rotation);
|
||||||
|
mat4 fullModel = rootModel * model;
|
||||||
|
|
||||||
|
vec2 corners[4] = { {0,0}, {1,0}, {1,1}, {0,1} };
|
||||||
|
|
||||||
|
for (auto& corner : corners)
|
||||||
|
{
|
||||||
|
vec4 world = fullModel * vec4(corner, 0.0f, 1.0f);
|
||||||
|
minX = std::min(minX, world.x);
|
||||||
|
minY = std::min(minY, world.y);
|
||||||
|
maxX = std::max(maxX, world.x);
|
||||||
|
maxY = std::max(maxY, world.y);
|
||||||
|
any = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!any) return vec4(-1.0f);
|
||||||
|
return {minX, minY, maxX - minX, maxY - minY};
|
||||||
|
}
|
@@ -13,7 +13,9 @@
|
|||||||
#define ANM2_FRAME_DELAY_MIN 1
|
#define ANM2_FRAME_DELAY_MIN 1
|
||||||
#define ANM2_STRING_MAX 0xFF
|
#define ANM2_STRING_MAX 0xFF
|
||||||
|
|
||||||
|
#define ANM2_EMPTY_ERROR "No path given for anm2"
|
||||||
#define ANM2_READ_ERROR "Failed to read anm2 from file: {}"
|
#define ANM2_READ_ERROR "Failed to read anm2 from file: {}"
|
||||||
|
#define ANM2_PARSE_ERROR "Failed to parse anm2: {} ({})"
|
||||||
#define ANM2_READ_INFO "Read anm2 from file: {}"
|
#define ANM2_READ_INFO "Read anm2 from file: {}"
|
||||||
#define ANM2_WRITE_ERROR "Failed to write anm2 to file: {}"
|
#define ANM2_WRITE_ERROR "Failed to write anm2 to file: {}"
|
||||||
#define ANM2_WRITE_INFO "Wrote anm2 to file: {}"
|
#define ANM2_WRITE_INFO "Wrote anm2 to file: {}"
|
||||||
@@ -272,7 +274,7 @@ void anm2_layer_remove(Anm2* self, s32 id);
|
|||||||
void anm2_null_add(Anm2* self);
|
void anm2_null_add(Anm2* self);
|
||||||
void anm2_null_remove(Anm2* self, s32 id);
|
void anm2_null_remove(Anm2* self, s32 id);
|
||||||
bool anm2_serialize(Anm2* self, const std::string& path);
|
bool anm2_serialize(Anm2* self, const std::string& path);
|
||||||
bool anm2_deserialize(Anm2* self, const std::string& path);
|
bool anm2_deserialize(Anm2* self, const std::string& path, bool isTextures = true);
|
||||||
void anm2_new(Anm2* self);
|
void anm2_new(Anm2* self);
|
||||||
void anm2_free(Anm2* self);
|
void anm2_free(Anm2* self);
|
||||||
void anm2_created_on_set(Anm2* self);
|
void anm2_created_on_set(Anm2* self);
|
||||||
@@ -297,3 +299,4 @@ void anm2_scale(Anm2* self, f32 scale);
|
|||||||
void anm2_generate_from_grid(Anm2* self, Anm2Reference* reference, vec2 startPosition, vec2 size, vec2 pivot, s32 columns, s32 count, s32 delay);
|
void anm2_generate_from_grid(Anm2* self, Anm2Reference* reference, vec2 startPosition, vec2 size, vec2 pivot, s32 columns, s32 count, s32 delay);
|
||||||
void anm2_spritesheet_texture_pixels_upload(Anm2* self);
|
void anm2_spritesheet_texture_pixels_upload(Anm2* self);
|
||||||
void anm2_spritesheet_texture_pixels_download(Anm2* self);
|
void anm2_spritesheet_texture_pixels_download(Anm2* self);
|
||||||
|
vec4 anm2_animation_rect_get(Anm2* anm2, Anm2Reference* reference, bool isRootTransform);
|
@@ -241,36 +241,3 @@ void canvas_free(Canvas* self)
|
|||||||
glDeleteBuffers(1, &self->textureVBO);
|
glDeleteBuffers(1, &self->textureVBO);
|
||||||
glDeleteBuffers(1, &self->textureEBO);
|
glDeleteBuffers(1, &self->textureEBO);
|
||||||
}
|
}
|
||||||
|
|
||||||
mat4 canvas_model_get(vec2 size, vec2 position, vec2 pivot, vec2 scale, f32 rotation)
|
|
||||||
{
|
|
||||||
vec2 scaleAbsolute = glm::abs(scale);
|
|
||||||
vec2 scaleSign = glm::sign(scale);
|
|
||||||
vec2 pivotScaled = pivot * scaleAbsolute;
|
|
||||||
vec2 sizeScaled = size * scaleAbsolute;
|
|
||||||
|
|
||||||
mat4 model(1.0f);
|
|
||||||
model = glm::translate(model, vec3(position - pivotScaled, 0.0f));
|
|
||||||
model = glm::translate(model, vec3(pivotScaled, 0.0f));
|
|
||||||
model = glm::scale(model, vec3(scaleSign, 1.0f));
|
|
||||||
model = glm::rotate(model, glm::radians(rotation), vec3(0, 0, 1));
|
|
||||||
model = glm::translate(model, vec3(-pivotScaled, 0.0f));
|
|
||||||
model = glm::scale(model, vec3(sizeScaled, 1.0f));
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
|
|
||||||
mat4 canvas_parent_model_get(vec2 position, vec2 pivot, vec2 scale, f32 rotation)
|
|
||||||
{
|
|
||||||
vec2 scaleSign = glm::sign(scale);
|
|
||||||
vec2 scaleAbsolute = glm::abs(scale);
|
|
||||||
f32 handedness = (scaleSign.x * scaleSign.y) < 0.0f ? -1.0f : 1.0f;
|
|
||||||
|
|
||||||
mat4 local(1.0f);
|
|
||||||
local = glm::translate(local, vec3(pivot, 0.0f));
|
|
||||||
local = glm::scale(local, vec3(scaleSign, 1.0f));
|
|
||||||
local = glm::rotate(local, glm::radians(rotation) * handedness, vec3(0, 0, 1));
|
|
||||||
local = glm::translate(local, vec3(-pivot, 0.0f));
|
|
||||||
local = glm::scale(local, vec3(scaleAbsolute, 1.0f));
|
|
||||||
|
|
||||||
return glm::translate(mat4(1.0f), vec3(position, 0.0f)) * local;
|
|
||||||
}
|
|
@@ -77,8 +77,6 @@ void canvas_rect_draw(Canvas* self, const GLuint& shader, const mat4& transform,
|
|||||||
void canvas_framebuffer_resize_check(Canvas* self);
|
void canvas_framebuffer_resize_check(Canvas* self);
|
||||||
void canvas_unbind(void);
|
void canvas_unbind(void);
|
||||||
void canvas_viewport_set(Canvas* self);
|
void canvas_viewport_set(Canvas* self);
|
||||||
mat4 canvas_model_get(vec2 size = {}, vec2 position = {}, vec2 pivot = {}, vec2 scale = vec2(1.0f), f32 rotation = {});
|
|
||||||
mat4 canvas_parent_model_get(vec2 position = {}, vec2 pivot = {}, vec2 scale = vec2(1.0f), f32 rotation = {});
|
|
||||||
|
|
||||||
void canvas_texture_draw
|
void canvas_texture_draw
|
||||||
(
|
(
|
||||||
|
@@ -30,7 +30,7 @@ void editor_draw(Editor* self)
|
|||||||
{
|
{
|
||||||
Texture& texture = spritesheet->texture;
|
Texture& texture = spritesheet->texture;
|
||||||
|
|
||||||
mat4 spritesheetTransform = transform * canvas_model_get(texture.size);
|
mat4 spritesheetTransform = transform * quad_model_get(texture.size);
|
||||||
canvas_texture_draw(&self->canvas, shaderTexture, texture.id, spritesheetTransform);
|
canvas_texture_draw(&self->canvas, shaderTexture, texture.id, spritesheetTransform);
|
||||||
|
|
||||||
if (self->settings->editorIsBorder)
|
if (self->settings->editorIsBorder)
|
||||||
@@ -40,10 +40,10 @@ void editor_draw(Editor* self)
|
|||||||
|
|
||||||
if (frame)
|
if (frame)
|
||||||
{
|
{
|
||||||
mat4 cropTransform = transform * canvas_model_get(frame->size, frame->crop);
|
mat4 cropTransform = transform * quad_model_get(frame->size, frame->crop);
|
||||||
canvas_rect_draw(&self->canvas, shaderLine, cropTransform, EDITOR_FRAME_COLOR);
|
canvas_rect_draw(&self->canvas, shaderLine, cropTransform, EDITOR_FRAME_COLOR);
|
||||||
|
|
||||||
mat4 pivotTransform = transform * canvas_model_get(CANVAS_PIVOT_SIZE, frame->crop + frame->pivot, CANVAS_PIVOT_SIZE * 0.5f);
|
mat4 pivotTransform = transform * quad_model_get(CANVAS_PIVOT_SIZE, frame->crop + frame->pivot, CANVAS_PIVOT_SIZE * 0.5f);
|
||||||
f32 vertices[] = ATLAS_UV_VERTICES(ATLAS_PIVOT);
|
f32 vertices[] = ATLAS_UV_VERTICES(ATLAS_PIVOT);
|
||||||
canvas_texture_draw(&self->canvas, shaderTexture, self->resources->atlas.id, pivotTransform, vertices, EDITOR_PIVOT_COLOR);
|
canvas_texture_draw(&self->canvas, shaderTexture, self->resources->atlas.id, pivotTransform, vertices, EDITOR_PIVOT_COLOR);
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,5 @@
|
|||||||
#include "ffmpeg.h"
|
#include "ffmpeg.h"
|
||||||
|
|
||||||
static std::string ffmpeg_log_path_get(void)
|
|
||||||
{
|
|
||||||
return preferences_path_get() + FFMPEG_LOG_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ffmpeg_render
|
ffmpeg_render
|
||||||
(
|
(
|
||||||
@@ -35,13 +30,8 @@ ffmpeg_render
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ffmpeg output will be piped into the log
|
|
||||||
std::string logOutput = " 2>> \"" + ffmpeg_log_path_get() + "\"";
|
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
command = string_quote(command) + logOutput;
|
command = string_quote(command);
|
||||||
#else
|
|
||||||
command += logOutput;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
log_command(command);
|
log_command(command);
|
||||||
|
@@ -4,8 +4,6 @@
|
|||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
|
|
||||||
#define FFMPEG_POPEN_ERROR "popen() (for FFmpeg) failed!\n{}"
|
#define FFMPEG_POPEN_ERROR "popen() (for FFmpeg) failed!\n{}"
|
||||||
#define FFMPEG_LOG_BUFFER_SIZE 256
|
|
||||||
#define FFMPEG_LOG_PATH "ffmpeg.txt"
|
|
||||||
|
|
||||||
static constexpr const char* FFMPEG_GIF_FORMAT =
|
static constexpr const char* FFMPEG_GIF_FORMAT =
|
||||||
"\"{0}\" -y "
|
"\"{0}\" -y "
|
||||||
|
@@ -42,7 +42,7 @@ void generate_preview_draw(GeneratePreview* self)
|
|||||||
vec2 uvMax = (crop + size) / vec2(texture.size);
|
vec2 uvMax = (crop + size) / vec2(texture.size);
|
||||||
f32 vertices[] = UV_VERTICES(uvMin, uvMax);
|
f32 vertices[] = UV_VERTICES(uvMin, uvMax);
|
||||||
|
|
||||||
mat4 generateTransform = transform * canvas_model_get(size, {}, pivot);
|
mat4 generateTransform = transform * quad_model_get(size, {}, pivot);
|
||||||
canvas_texture_draw(&self->canvas, shaderTexture, texture.id, generateTransform, vertices, COLOR_OPAQUE, COLOR_OFFSET_NONE);
|
canvas_texture_draw(&self->canvas, shaderTexture, texture.id, generateTransform, vertices, COLOR_OPAQUE, COLOR_OFFSET_NONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
302
src/imgui.cpp
302
src/imgui.cpp
@@ -43,7 +43,7 @@ static bool _imgui_window_color_from_position_get(SDL_Window* self, const vec2&
|
|||||||
|
|
||||||
static void _imgui_anm2_open(Imgui* self, const std::string& path)
|
static void _imgui_anm2_open(Imgui* self, const std::string& path)
|
||||||
{
|
{
|
||||||
imgui_file_new(self);
|
imgui_anm2_new(self);
|
||||||
|
|
||||||
if (anm2_deserialize(self->anm2, path))
|
if (anm2_deserialize(self->anm2, path))
|
||||||
{
|
{
|
||||||
@@ -74,12 +74,6 @@ static void _imgui_spritesheet_add(Imgui* self, const std::string& path)
|
|||||||
std::filesystem::current_path(workingPath);
|
std::filesystem::current_path(workingPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static void _imgui_clipboard_hovered_item_set(Imgui* self, const T& data)
|
|
||||||
{
|
|
||||||
self->clipboard->hoveredItem = ClipboardItem(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool _imgui_is_window_hovered(void)
|
static bool _imgui_is_window_hovered(void)
|
||||||
{
|
{
|
||||||
return ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem);
|
return ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem);
|
||||||
@@ -128,7 +122,7 @@ static ImVec2 _imgui_item_size_get(const ImguiItem& self, ImguiItemType type)
|
|||||||
if (self.is_row())
|
if (self.is_row())
|
||||||
size.x = (ImGui::GetWindowSize().x - (ImGui::GetStyle().ItemSpacing.x * (self.rowCount + 1))) / self.rowCount;
|
size.x = (ImGui::GetWindowSize().x - (ImGui::GetStyle().ItemSpacing.x * (self.rowCount + 1))) / self.rowCount;
|
||||||
else if (self.isSizeToText)
|
else if (self.isSizeToText)
|
||||||
size.x = (ImGui::CalcTextSize(self.label_get()).x + ImGui::GetStyle().FramePadding.x);
|
size.x = (ImGui::CalcTextSize(self.label_get().c_str()).x + ImGui::GetStyle().FramePadding.x);
|
||||||
else if (!self.is_size())
|
else if (!self.is_size())
|
||||||
size.x = ImGui::CalcItemWidth();
|
size.x = ImGui::CalcItemWidth();
|
||||||
break;
|
break;
|
||||||
@@ -188,16 +182,6 @@ static void _imgui_item_pre(const ImguiItem& self, ImguiItemType type)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
if (self.is_hotkey())
|
|
||||||
{
|
|
||||||
std::string chordString = imgui_string_from_chord_get(imgui->hotkeys[self.hotkey]);
|
|
||||||
if (isShortcutInLabel)
|
|
||||||
label += std::format(IMGUI_LABEL_SHORTCUT_FORMAT, chordString);
|
|
||||||
tooltip += std::format(IMGUI_TOOLTIP_SHORTCUT_FORMAT, chordString);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _imgui_item_post(const ImguiItem& self, Imgui* imgui, ImguiItemType type, bool& isActivated)
|
static void _imgui_item_post(const ImguiItem& self, Imgui* imgui, ImguiItemType type, bool& isActivated)
|
||||||
@@ -238,7 +222,7 @@ static void _imgui_item_post(const ImguiItem& self, Imgui* imgui, ImguiItemType
|
|||||||
if (!self.isDisabled) isActivated = true;
|
if (!self.isDisabled) isActivated = true;
|
||||||
|
|
||||||
if (self.is_tooltip() && ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal))
|
if (self.is_tooltip() && ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal))
|
||||||
ImGui::SetTooltip(self.tooltip.c_str());
|
ImGui::SetTooltip(self.tooltip_get().c_str());
|
||||||
|
|
||||||
if (isActivated)
|
if (isActivated)
|
||||||
{
|
{
|
||||||
@@ -429,32 +413,32 @@ static bool NAME(const ImguiItem& self, const ImguiItem& checkboxItem, Imgui* im
|
|||||||
|
|
||||||
#define IMGUI_ITEM_DISABLED_GET(VALUE, ITEM, CONDITION) ImguiItem VALUE = ITEM; VALUE.isDisabled = CONDITION;
|
#define IMGUI_ITEM_DISABLED_GET(VALUE, ITEM, CONDITION) ImguiItem VALUE = ITEM; VALUE.isDisabled = CONDITION;
|
||||||
|
|
||||||
IMGUI_ITEM_FUNCTION(_imgui_begin, IMGUI_WINDOW, ImGui::Begin(self.label_get(), nullptr, self.flags));
|
IMGUI_ITEM_FUNCTION(_imgui_begin, IMGUI_WINDOW, ImGui::Begin(self.label_get().c_str(), nullptr, self.flags));
|
||||||
#define IMGUI_BEGIN_OR_RETURN(item, imgui) if (!_imgui_begin(item, imgui)) { _imgui_end(); return; }
|
#define IMGUI_BEGIN_OR_RETURN(item, imgui) if (!_imgui_begin(item, imgui)) { _imgui_end(); return; }
|
||||||
static void _imgui_end(void){ImGui::End();}
|
static void _imgui_end(void){ImGui::End();}
|
||||||
IMGUI_ITEM_VOID_FUNCTION(_imgui_dockspace, IMGUI_DOCKSPACE, ImGui::DockSpace(ImGui::GetID(self.label_get()), self.size, self.flags));
|
IMGUI_ITEM_VOID_FUNCTION(_imgui_dockspace, IMGUI_DOCKSPACE, ImGui::DockSpace(ImGui::GetID(self.label_get().c_str()), self.size, self.flags));
|
||||||
IMGUI_ITEM_FUNCTION(_imgui_begin_child, IMGUI_CHILD, ImGui::BeginChild(self.label_get(), self.size, self.flags, self.windowFlags));
|
IMGUI_ITEM_FUNCTION(_imgui_begin_child, IMGUI_CHILD, ImGui::BeginChild(self.label_get().c_str(), self.size, self.flags, self.windowFlags));
|
||||||
static void _imgui_end_child(void) {ImGui::EndChild(); }
|
static void _imgui_end_child(void) {ImGui::EndChild(); }
|
||||||
IMGUI_ITEM_VOID_FUNCTION(_imgui_text, IMGUI_TEXT, ImGui::Text(self.label_get()));
|
IMGUI_ITEM_VOID_FUNCTION(_imgui_text, IMGUI_TEXT, ImGui::Text(self.label_get().c_str()));
|
||||||
IMGUI_ITEM_FUNCTION(_imgui_button, IMGUI_BUTTON, ImGui::Button(self.label_get(), _imgui_item_size_get(self, type)));
|
IMGUI_ITEM_FUNCTION(_imgui_button, IMGUI_BUTTON, ImGui::Button(self.label_get().c_str(), _imgui_item_size_get(self, type)));
|
||||||
IMGUI_ITEM_FUNCTION(_imgui_begin_table, IMGUI_TABLE, ImGui::BeginTable(self.label_get(), self.value, self.flags));
|
IMGUI_ITEM_FUNCTION(_imgui_begin_table, IMGUI_TABLE, ImGui::BeginTable(self.label_get().c_str(), self.value, self.flags));
|
||||||
static void _imgui_end_table(void) {ImGui::EndTable(); }
|
static void _imgui_end_table(void) {ImGui::EndTable(); }
|
||||||
static void _imgui_table_setup_column(const char* text) {ImGui::TableSetupColumn(text); }
|
static void _imgui_table_setup_column(const char* text) {ImGui::TableSetupColumn(text); }
|
||||||
static void _imgui_table_headers_row(void) {ImGui::TableHeadersRow(); }
|
static void _imgui_table_headers_row(void) {ImGui::TableHeadersRow(); }
|
||||||
static void _imgui_table_next_row(void) {ImGui::TableNextRow(); }
|
static void _imgui_table_next_row(void) {ImGui::TableNextRow(); }
|
||||||
static void _imgui_table_set_column_index(s32 index) {ImGui::TableSetColumnIndex(index); }
|
static void _imgui_table_set_column_index(s32 index) {ImGui::TableSetColumnIndex(index); }
|
||||||
IMGUI_ITEM_FUNCTION(_imgui_selectable, IMGUI_SELECTABLE, ImGui::Selectable(self.label_get(), self.isSelected, self.flags, _imgui_item_size_get(self, type)));
|
IMGUI_ITEM_FUNCTION(_imgui_selectable, IMGUI_SELECTABLE, ImGui::Selectable(self.label_get().c_str(), self.isSelected, self.flags, _imgui_item_size_get(self, type)));
|
||||||
IMGUI_ITEM_VALUE_FUNCTION(_imgui_radio_button, IMGUI_RADIO_BUTTON, s32, ImGui::RadioButton(self.label_get(), &value, self.value));
|
IMGUI_ITEM_VALUE_FUNCTION(_imgui_radio_button, IMGUI_RADIO_BUTTON, s32, ImGui::RadioButton(self.label_get().c_str(), &value, self.value));
|
||||||
IMGUI_ITEM_VALUE_FUNCTION(_imgui_color_button, IMGUI_COLOR_BUTTON, vec4, ImGui::ColorButton(self.label_get(), ImVec4(value), self.flags));
|
IMGUI_ITEM_VALUE_FUNCTION(_imgui_color_button, IMGUI_COLOR_BUTTON, vec4, ImGui::ColorButton(self.label_get().c_str(), ImVec4(value), self.flags));
|
||||||
IMGUI_ITEM_VALUE_FUNCTION(_imgui_checkbox, IMGUI_CHECKBOX, bool, ImGui::Checkbox(self.label_get(), &value));
|
IMGUI_ITEM_VALUE_FUNCTION(_imgui_checkbox, IMGUI_CHECKBOX, bool, ImGui::Checkbox(self.label_get().c_str(), &value));
|
||||||
IMGUI_ITEM_VALUE_CLAMP_FUNCTION(_imgui_input_int, IMGUI_INPUT_INT, s32, ImGui::InputInt(self.label_get(), &value, self.step, self.stepFast, self.flags));
|
IMGUI_ITEM_VALUE_CLAMP_FUNCTION(_imgui_input_int, IMGUI_INPUT_INT, s32, ImGui::InputInt(self.label_get().c_str(), &value, self.step, self.stepFast, self.flags));
|
||||||
IMGUI_ITEM_VALUE_CLAMP_FUNCTION(_imgui_input_int2, IMGUI_INPUT_INT, ivec2, ImGui::InputInt2(self.label_get(), value_ptr(value), self.flags));
|
IMGUI_ITEM_VALUE_CLAMP_FUNCTION(_imgui_input_int2, IMGUI_INPUT_INT, ivec2, ImGui::InputInt2(self.label_get().c_str(), value_ptr(value), self.flags));
|
||||||
IMGUI_ITEM_VALUE_CLAMP_FUNCTION(_imgui_input_float, IMGUI_INPUT_FLOAT, f32, ImGui::InputFloat(self.label_get(), &value, self.step, self.stepFast, _imgui_f32_format_get(self, value), self.flags));
|
IMGUI_ITEM_VALUE_CLAMP_FUNCTION(_imgui_input_float, IMGUI_INPUT_FLOAT, f32, ImGui::InputFloat(self.label_get().c_str(), &value, self.step, self.stepFast, _imgui_f32_format_get(self, value), self.flags));
|
||||||
IMGUI_ITEM_VALUE_FUNCTION(_imgui_slider_float, IMGUI_SLIDER_FLOAT, f32, ImGui::SliderFloat(self.label_get(), &value, self.min, self.max, _imgui_f32_format_get(self, value), self.flags));
|
IMGUI_ITEM_VALUE_FUNCTION(_imgui_slider_float, IMGUI_SLIDER_FLOAT, f32, ImGui::SliderFloat(self.label_get().c_str(), &value, self.min, self.max, _imgui_f32_format_get(self, value), self.flags));
|
||||||
IMGUI_ITEM_VALUE_FUNCTION(_imgui_drag_float, IMGUI_DRAG_FLOAT, f32, ImGui::DragFloat(self.label_get(), &value, self.speed, self.min, self.max, _imgui_f32_format_get(self, value)));
|
IMGUI_ITEM_VALUE_FUNCTION(_imgui_drag_float, IMGUI_DRAG_FLOAT, f32, ImGui::DragFloat(self.label_get().c_str(), &value, self.speed, self.min, self.max, _imgui_f32_format_get(self, value)));
|
||||||
IMGUI_ITEM_VALUE_FUNCTION(_imgui_drag_float2, IMGUI_DRAG_FLOAT, vec2, ImGui::DragFloat2(self.label_get(), value_ptr(value), self.speed, self.min, self.max, _imgui_vec2_format_get(self, value)));
|
IMGUI_ITEM_VALUE_FUNCTION(_imgui_drag_float2, IMGUI_DRAG_FLOAT, vec2, ImGui::DragFloat2(self.label_get().c_str(), value_ptr(value), self.speed, self.min, self.max, _imgui_vec2_format_get(self, value)));
|
||||||
IMGUI_ITEM_VALUE_FUNCTION(_imgui_color_edit3, IMGUI_COLOR_EDIT, vec3, ImGui::ColorEdit3(self.label_get(), value_ptr(value), self.flags));
|
IMGUI_ITEM_VALUE_FUNCTION(_imgui_color_edit3, IMGUI_COLOR_EDIT, vec3, ImGui::ColorEdit3(self.label_get().c_str(), value_ptr(value), self.flags));
|
||||||
IMGUI_ITEM_VALUE_FUNCTION(_imgui_color_edit4, IMGUI_COLOR_EDIT, vec4, ImGui::ColorEdit4(self.label_get(), value_ptr(value), self.flags));
|
IMGUI_ITEM_VALUE_FUNCTION(_imgui_color_edit4, IMGUI_COLOR_EDIT, vec4, ImGui::ColorEdit4(self.label_get().c_str(), value_ptr(value), self.flags));
|
||||||
IMGUI_ITEM_CHECKBOX_FUNCTION(_imgui_checkbox_selectable, _imgui_selectable(self, imgui));
|
IMGUI_ITEM_CHECKBOX_FUNCTION(_imgui_checkbox_selectable, _imgui_selectable(self, imgui));
|
||||||
IMGUI_ITEM_CHECKBOX_VALUE_FUNCTION(_imgui_checkbox_checkbox, bool, _imgui_checkbox(self, imgui, value));
|
IMGUI_ITEM_CHECKBOX_VALUE_FUNCTION(_imgui_checkbox_checkbox, bool, _imgui_checkbox(self, imgui, value));
|
||||||
IMGUI_ITEM_CHECKBOX_VALUE_FUNCTION(_imgui_checkbox_input_int, s32, _imgui_input_int(self, imgui, value));
|
IMGUI_ITEM_CHECKBOX_VALUE_FUNCTION(_imgui_checkbox_input_int, s32, _imgui_input_int(self, imgui, value));
|
||||||
@@ -467,7 +451,7 @@ static bool _imgui_input_text(const ImguiItem& self, Imgui* imgui, std::string&
|
|||||||
{
|
{
|
||||||
value.resize(self.max);
|
value.resize(self.max);
|
||||||
_imgui_item_pre(self, IMGUI_INPUT_TEXT);
|
_imgui_item_pre(self, IMGUI_INPUT_TEXT);
|
||||||
bool isActivated = ImGui::InputText(self.label_get(), value.data(), self.max, self.flags);
|
bool isActivated = ImGui::InputText(self.label_get().c_str(), value.data(), self.max, self.flags);
|
||||||
_imgui_item_post(self, imgui, IMGUI_INPUT_TEXT, isActivated);
|
_imgui_item_post(self, imgui, IMGUI_INPUT_TEXT, isActivated);
|
||||||
return isActivated;
|
return isActivated;
|
||||||
}
|
}
|
||||||
@@ -481,7 +465,7 @@ static bool _imgui_combo(ImguiItem self, Imgui* imgui, s32* value)
|
|||||||
|
|
||||||
_imgui_item_pre(self, IMGUI_COMBO);
|
_imgui_item_pre(self, IMGUI_COMBO);
|
||||||
|
|
||||||
bool isActivated = ImGui::Combo(self.label_get(), value, cStrings.data(), (s32)self.items.size());
|
bool isActivated = ImGui::Combo(self.label_get().c_str(), value, cStrings.data(), (s32)self.items.size());
|
||||||
if (_imgui_is_input_default())
|
if (_imgui_is_input_default())
|
||||||
{
|
{
|
||||||
*value = self.value;
|
*value = self.value;
|
||||||
@@ -499,7 +483,7 @@ IMGUI_ITEM_CUSTOM_FUNCTION(_imgui_atlas_button, IMGUI_ATLAS_BUTTON,
|
|||||||
|
|
||||||
if (self.is_size())
|
if (self.is_size())
|
||||||
{
|
{
|
||||||
isActivated = ImGui::Button(self.label_get(), size);
|
isActivated = ImGui::Button(self.label_get().c_str(), size);
|
||||||
|
|
||||||
ImVec2 start = ImGui::GetItemRectMin() + self.atlasOffset;
|
ImVec2 start = ImGui::GetItemRectMin() + self.atlasOffset;
|
||||||
ImVec2 end = start + ImVec2(ATLAS_SIZE(self.atlas));
|
ImVec2 end = start + ImVec2(ATLAS_SIZE(self.atlas));
|
||||||
@@ -507,7 +491,7 @@ IMGUI_ITEM_CUSTOM_FUNCTION(_imgui_atlas_button, IMGUI_ATLAS_BUTTON,
|
|||||||
ImGui::GetWindowDrawList()->AddImage(imgui->resources->atlas.id, start, end, ATLAS_UV_ARGS(self.atlas));
|
ImGui::GetWindowDrawList()->AddImage(imgui->resources->atlas.id, start, end, ATLAS_UV_ARGS(self.atlas));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
isActivated = ImGui::ImageButton(self.label_get(), imgui->resources->atlas.id, size, ATLAS_UV_ARGS(self.atlas));
|
isActivated = ImGui::ImageButton(self.label_get().c_str(), imgui->resources->atlas.id, size, ATLAS_UV_ARGS(self.atlas));
|
||||||
});
|
});
|
||||||
|
|
||||||
static bool _imgui_selectable_input_int(const ImguiItem& self, Imgui* imgui, s32& value)
|
static bool _imgui_selectable_input_int(const ImguiItem& self, Imgui* imgui, s32& value)
|
||||||
@@ -592,7 +576,7 @@ static bool _imgui_option_popup(ImguiItem self, Imgui* imgui, ImguiPopupState* s
|
|||||||
|
|
||||||
if (state) *state = IMGUI_POPUP_STATE_CLOSED;
|
if (state) *state = IMGUI_POPUP_STATE_CLOSED;
|
||||||
|
|
||||||
if (imgui_begin_popup_modal(self.label_get(), imgui))
|
if (imgui_begin_popup_modal(self.label_get().c_str(), imgui))
|
||||||
{
|
{
|
||||||
if (state) *state = IMGUI_POPUP_STATE_OPEN;
|
if (state) *state = IMGUI_POPUP_STATE_OPEN;
|
||||||
|
|
||||||
@@ -1007,8 +991,8 @@ static void _imgui_timeline(Imgui* self)
|
|||||||
if (ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
if (ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
||||||
{
|
{
|
||||||
*self->reference = reference;
|
*self->reference = reference;
|
||||||
self->clipboard->location = hoverReference;
|
if (reference.itemType == ANM2_LAYER && reference.itemID != ID_NONE)
|
||||||
_imgui_spritesheet_editor_set(self, self->anm2->layers[self->reference->itemID].spritesheetID);
|
_imgui_spritesheet_editor_set(self, self->anm2->layers[self->reference->itemID].spritesheetID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1060,12 +1044,6 @@ static void _imgui_timeline(Imgui* self)
|
|||||||
|
|
||||||
if (_imgui_atlas_button(frameButton, self)) *self->reference = reference;
|
if (_imgui_atlas_button(frameButton, self)) *self->reference = reference;
|
||||||
|
|
||||||
if (ImGui::IsItemHovered())
|
|
||||||
{
|
|
||||||
Anm2FrameWithReference frameWithReference = {reference, frame};
|
|
||||||
_imgui_clipboard_hovered_item_set(self, frameWithReference);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::IsItemActivated())
|
if (ImGui::IsItemActivated())
|
||||||
{
|
{
|
||||||
if (type == ANM2_TRIGGERS || isModCtrl)
|
if (type == ANM2_TRIGGERS || isModCtrl)
|
||||||
@@ -1291,8 +1269,7 @@ static void _imgui_timeline(Imgui* self)
|
|||||||
imgui_end_popup(self);
|
imgui_end_popup(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_imgui_button(IMGUI_FIT_ANIMATION_LENGTH, self))
|
if (_imgui_button(IMGUI_FIT_ANIMATION_LENGTH, self)) anm2_animation_length_set(animation);
|
||||||
anm2_animation_length_set(animation);
|
|
||||||
|
|
||||||
_imgui_input_int(IMGUI_ANIMATION_LENGTH, self, animation->frameNum);
|
_imgui_input_int(IMGUI_ANIMATION_LENGTH, self, animation->frameNum);
|
||||||
_imgui_input_int(IMGUI_FPS, self, self->anm2->fps);
|
_imgui_input_int(IMGUI_FPS, self, self->anm2->fps);
|
||||||
@@ -1355,7 +1332,7 @@ static void _imgui_taskbar(Imgui* self)
|
|||||||
|
|
||||||
if (imgui_begin_popup(IMGUI_FILE.popup, self))
|
if (imgui_begin_popup(IMGUI_FILE.popup, self))
|
||||||
{
|
{
|
||||||
_imgui_selectable(IMGUI_NEW.copy({self->anm2->path.empty()}), self);
|
_imgui_selectable(IMGUI_NEW, self);
|
||||||
_imgui_selectable(IMGUI_OPEN, self);
|
_imgui_selectable(IMGUI_OPEN, self);
|
||||||
_imgui_selectable(IMGUI_SAVE.copy({self->anm2->path.empty()}), self);
|
_imgui_selectable(IMGUI_SAVE.copy({self->anm2->path.empty()}), self);
|
||||||
_imgui_selectable(IMGUI_SAVE_AS.copy({self->anm2->path.empty()}), self);
|
_imgui_selectable(IMGUI_SAVE_AS.copy({self->anm2->path.empty()}), self);
|
||||||
@@ -1664,9 +1641,15 @@ static void _imgui_taskbar(Imgui* self)
|
|||||||
rendering_end();
|
rendering_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_imgui_begin_child(IMGUI_RENDERING_ANIMATION_CHILD, self);
|
||||||
|
|
||||||
f32 progress = self->preview->time / (animation->frameNum - 1);
|
f32 progress = self->preview->time / (animation->frameNum - 1);
|
||||||
ImGui::ProgressBar(progress);
|
ImGui::ProgressBar(progress);
|
||||||
|
|
||||||
|
_imgui_text(IMGUI_RENDERING_ANIMATION_INFO, self);
|
||||||
|
|
||||||
|
_imgui_end_child(); //IMGUI_RENDERING_ANIMATION_CHILD
|
||||||
|
|
||||||
if (_imgui_button(IMGUI_RENDERING_ANIMATION_CANCEL, self))
|
if (_imgui_button(IMGUI_RENDERING_ANIMATION_CANCEL, self))
|
||||||
self->preview->isRenderCancelled = true;
|
self->preview->isRenderCancelled = true;
|
||||||
|
|
||||||
@@ -1868,13 +1851,6 @@ static void _imgui_animations(Imgui* self)
|
|||||||
anm2_reference_item_clear(self->reference);
|
anm2_reference_item_clear(self->reference);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::IsItemHovered())
|
|
||||||
{
|
|
||||||
Anm2AnimationWithID animationWithID = {id, animation};
|
|
||||||
_imgui_clipboard_hovered_item_set(self, animationWithID);
|
|
||||||
self->clipboard->location = (s32)id;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None))
|
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None))
|
||||||
{
|
{
|
||||||
if (ImGui::IsDragDropActive()) ImGui::SetNextItemWidth(_imgui_item_size_get(animationItem, IMGUI_SELECTABLE).x);
|
if (ImGui::IsDragDropActive()) ImGui::SetNextItemWidth(_imgui_item_size_get(animationItem, IMGUI_SELECTABLE).x);
|
||||||
@@ -2298,6 +2274,22 @@ static void _imgui_animation_preview(Imgui* self)
|
|||||||
_imgui_begin_child(IMGUI_CANVAS_VIEW_CHILD, self);
|
_imgui_begin_child(IMGUI_CANVAS_VIEW_CHILD, self);
|
||||||
_imgui_drag_float(IMGUI_CANVAS_ZOOM, self, zoom);
|
_imgui_drag_float(IMGUI_CANVAS_ZOOM, self, zoom);
|
||||||
if (_imgui_button(IMGUI_ANIMATION_PREVIEW_CENTER_VIEW.copy({pan == vec2()}), self)) pan = vec2();
|
if (_imgui_button(IMGUI_ANIMATION_PREVIEW_CENTER_VIEW.copy({pan == vec2()}), self)) pan = vec2();
|
||||||
|
if (_imgui_button(IMGUI_ANIMATION_PREVIEW_FIT.copy({self->reference->animationID == ID_NONE}), self))
|
||||||
|
{
|
||||||
|
vec4 rect = anm2_animation_rect_get(self->anm2, self->reference, self->settings->previewIsRootTransform);
|
||||||
|
|
||||||
|
if (rect != vec4(-1.0f) && (rect.z > 0 && rect.w > 0))
|
||||||
|
{
|
||||||
|
f32 scaleX = self->preview->canvas.size.x / rect.z;
|
||||||
|
f32 scaleY = self->preview->canvas.size.y / rect.w;
|
||||||
|
f32 fitScale = std::min(scaleX, scaleY);
|
||||||
|
|
||||||
|
zoom = UNIT_TO_PERCENT(fitScale);
|
||||||
|
|
||||||
|
vec2 rectCenter = { rect.x + rect.z * 0.5f, rect.y + rect.w * 0.5f };
|
||||||
|
pan = -rectCenter * fitScale;
|
||||||
|
}
|
||||||
|
}
|
||||||
ImGui::Text(mousePositionString.c_str());
|
ImGui::Text(mousePositionString.c_str());
|
||||||
_imgui_end_child(); //IMGUI_CANVAS_VIEW_CHILD
|
_imgui_end_child(); //IMGUI_CANVAS_VIEW_CHILD
|
||||||
|
|
||||||
@@ -2342,7 +2334,7 @@ static void _imgui_animation_preview(Imgui* self)
|
|||||||
_imgui_checkbox(IMGUI_CANVAS_TRIGGERS, self, self->settings->previewIsTriggers);
|
_imgui_checkbox(IMGUI_CANVAS_TRIGGERS, self, self->settings->previewIsTriggers);
|
||||||
_imgui_checkbox(IMGUI_CANVAS_PIVOTS, self, self->settings->previewIsPivots);
|
_imgui_checkbox(IMGUI_CANVAS_PIVOTS, self, self->settings->previewIsPivots);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
_imgui_checkbox(IMGUI_CANVAS_TARGETS, self, self->settings->previewIsTargets);
|
_imgui_checkbox(IMGUI_CANVAS_ICONS, self, self->settings->previewIsIcons);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
_imgui_checkbox(IMGUI_CANVAS_BORDER, self, self->settings->previewIsBorder);
|
_imgui_checkbox(IMGUI_CANVAS_BORDER, self, self->settings->previewIsBorder);
|
||||||
_imgui_end_child(); // IMGUI_CANVAS_HELPER_CHILD
|
_imgui_end_child(); // IMGUI_CANVAS_HELPER_CHILD
|
||||||
@@ -2368,10 +2360,14 @@ static void _imgui_animation_preview(Imgui* self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::IsItemHovered())
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
self->pendingCursor = TOOL_CURSORS[tool];
|
self->pendingCursor = TOOL_CURSORS[tool];
|
||||||
|
imgui_keyboard_nav_disable();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_imgui_end(); // IMGUI_ANIMATION_EDITOR
|
_imgui_end(); // IMGUI_ANIMATION_EDITOR
|
||||||
|
imgui_keyboard_nav_enable();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2392,58 +2388,66 @@ static void _imgui_animation_preview(Imgui* self)
|
|||||||
const ImVec2 mouseDelta = ImGui::GetIO().MouseDelta;
|
const ImVec2 mouseDelta = ImGui::GetIO().MouseDelta;
|
||||||
const f32 mouseWheel = ImGui::GetIO().MouseWheel;
|
const f32 mouseWheel = ImGui::GetIO().MouseWheel;
|
||||||
|
|
||||||
if (tool == TOOL_MOVE || tool == TOOL_SCALE || tool == TOOL_ROTATE)
|
|
||||||
if (isMouseClick || isLeft || isRight || isUp || isDown)
|
|
||||||
imgui_snapshot(self, IMGUI_ACTION_FRAME_TRANSFORM);
|
|
||||||
|
|
||||||
if ((tool == TOOL_PAN && isMouseDown) || isMouseMiddleDown)
|
|
||||||
pan += vec2(mouseDelta.x, mouseDelta.y);
|
|
||||||
|
|
||||||
Anm2Frame* frame = nullptr;
|
Anm2Frame* frame = nullptr;
|
||||||
|
|
||||||
if (self->reference->itemType != ANM2_TRIGGERS)
|
if (self->reference->itemType != ANM2_TRIGGERS)
|
||||||
frame = anm2_frame_from_reference(self->anm2, self->reference);
|
frame = anm2_frame_from_reference(self->anm2, self->reference);
|
||||||
|
|
||||||
if (frame)
|
f32 step = isMod ? TOOL_STEP_MOD : TOOL_STEP;
|
||||||
{
|
|
||||||
f32 step = isMod ? TOOL_STEP_MOD : TOOL_STEP;
|
|
||||||
|
|
||||||
switch (tool)
|
if ((tool == TOOL_PAN && isMouseDown) || isMouseMiddleDown)
|
||||||
{
|
pan += vec2(mouseDelta.x, mouseDelta.y);
|
||||||
case TOOL_MOVE:
|
|
||||||
if (isMouseDown)
|
switch (tool)
|
||||||
frame->position = vec2(mousePos);
|
{
|
||||||
else
|
case TOOL_MOVE:
|
||||||
{
|
if (!frame) break;
|
||||||
if (isLeft) frame->position.x -= step;
|
|
||||||
if (isRight) frame->position.x += step;
|
if (isMouseClick || isLeft || isRight || isUp || isDown)
|
||||||
if (isUp) frame->position.y -= step;
|
imgui_snapshot(self, IMGUI_ACTION_MOVE);
|
||||||
if (isDown) frame->position.y += step;
|
|
||||||
}
|
if (isMouseDown)
|
||||||
break;
|
frame->position = vec2(mousePos);
|
||||||
case TOOL_ROTATE:
|
else
|
||||||
if (isMouseDown)
|
{
|
||||||
frame->rotation += mouseDelta.x;
|
if (isLeft) frame->position.x -= step;
|
||||||
else
|
if (isRight) frame->position.x += step;
|
||||||
{
|
if (isUp) frame->position.y -= step;
|
||||||
if (isLeft || isUp) frame->rotation -= step;
|
if (isDown) frame->position.y += step;
|
||||||
if (isRight || isDown) frame->rotation += step;
|
}
|
||||||
}
|
break;
|
||||||
break;
|
case TOOL_ROTATE:
|
||||||
case TOOL_SCALE:
|
if (!frame) break;
|
||||||
if (isMouseDown)
|
|
||||||
frame->scale += vec2(mouseDelta.x, mouseDelta.y);
|
if (isMouseClick || isLeft || isRight || isUp || isDown)
|
||||||
else
|
imgui_snapshot(self, IMGUI_ACTION_ROTATE);
|
||||||
{
|
|
||||||
if (isLeft) frame->scale.x -= step;
|
if (isMouseDown)
|
||||||
if (isRight) frame->scale.x += step;
|
frame->rotation += mouseDelta.x;
|
||||||
if (isUp) frame->scale.y -= step;
|
else
|
||||||
if (isDown) frame->scale.y += step;
|
{
|
||||||
}
|
if (isLeft || isUp) frame->rotation -= step;
|
||||||
break;
|
if (isRight || isDown) frame->rotation += step;
|
||||||
default:
|
}
|
||||||
break;
|
break;
|
||||||
}
|
case TOOL_SCALE:
|
||||||
|
if (!frame) break;
|
||||||
|
|
||||||
|
if (isMouseClick || isLeft || isRight || isUp || isDown)
|
||||||
|
imgui_snapshot(self, IMGUI_ACTION_SCALE);
|
||||||
|
|
||||||
|
if (isMouseDown)
|
||||||
|
frame->scale += vec2(mouseDelta.x, mouseDelta.y);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (isLeft) frame->scale.x -= step;
|
||||||
|
if (isRight) frame->scale.x += step;
|
||||||
|
if (isUp) frame->scale.y -= step;
|
||||||
|
if (isDown) frame->scale.y += step;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mouseWheel != 0 || isZoomIn || isZoomOut)
|
if (mouseWheel != 0 || isZoomIn || isZoomOut)
|
||||||
@@ -2499,10 +2503,14 @@ static void _imgui_spritesheet_editor(Imgui* self)
|
|||||||
ImGui::Image(self->editor->canvas.framebuffer, vec2(size));
|
ImGui::Image(self->editor->canvas.framebuffer, vec2(size));
|
||||||
|
|
||||||
if (ImGui::IsItemHovered())
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
self->pendingCursor = TOOL_CURSORS[tool];
|
self->pendingCursor = TOOL_CURSORS[tool];
|
||||||
|
imgui_keyboard_nav_disable();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_imgui_end(); // IMGUI_SPRITESHEET_EDITOR
|
_imgui_end(); // IMGUI_SPRITESHEET_EDITOR
|
||||||
|
imgui_keyboard_nav_enable();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2510,6 +2518,12 @@ static void _imgui_spritesheet_editor(Imgui* self)
|
|||||||
|
|
||||||
mousePos = vec2(ImGui::GetMousePos() - editorCursorScreenPos - pan) / PERCENT_TO_UNIT(zoom);
|
mousePos = vec2(ImGui::GetMousePos() - editorCursorScreenPos - pan) / PERCENT_TO_UNIT(zoom);
|
||||||
|
|
||||||
|
const bool isLeft = ImGui::IsKeyPressed(IMGUI_INPUT_LEFT);
|
||||||
|
const bool isRight = ImGui::IsKeyPressed(IMGUI_INPUT_RIGHT);
|
||||||
|
const bool isUp = ImGui::IsKeyPressed(IMGUI_INPUT_UP);
|
||||||
|
const bool isDown = ImGui::IsKeyPressed(IMGUI_INPUT_DOWN);
|
||||||
|
const bool isShift = ImGui::IsKeyDown(IMGUI_INPUT_SHIFT);
|
||||||
|
const bool isCtrl = ImGui::IsKeyDown(IMGUI_INPUT_CTRL);
|
||||||
const bool isMouseClick = ImGui::IsMouseClicked(ImGuiMouseButton_Left);
|
const bool isMouseClick = ImGui::IsMouseClicked(ImGuiMouseButton_Left);
|
||||||
const bool isMouseDown = ImGui::IsMouseDown(ImGuiMouseButton_Left);
|
const bool isMouseDown = ImGui::IsMouseDown(ImGuiMouseButton_Left);
|
||||||
const bool isMouseMiddleDown = ImGui::IsMouseDown(ImGuiMouseButton_Middle);
|
const bool isMouseMiddleDown = ImGui::IsMouseDown(ImGuiMouseButton_Middle);
|
||||||
@@ -2518,9 +2532,6 @@ static void _imgui_spritesheet_editor(Imgui* self)
|
|||||||
const f32 mouseWheel = ImGui::GetIO().MouseWheel;
|
const f32 mouseWheel = ImGui::GetIO().MouseWheel;
|
||||||
const ImVec2 mouseDelta = ImGui::GetIO().MouseDelta;
|
const ImVec2 mouseDelta = ImGui::GetIO().MouseDelta;
|
||||||
|
|
||||||
if ((tool == TOOL_PAN && isMouseDown) || isMouseMiddleDown)
|
|
||||||
pan += vec2(mouseDelta.x, mouseDelta.y);
|
|
||||||
|
|
||||||
Anm2Frame* frame = nullptr;
|
Anm2Frame* frame = nullptr;
|
||||||
if (self->reference->itemType == ANM2_LAYER)
|
if (self->reference->itemType == ANM2_LAYER)
|
||||||
frame = anm2_frame_from_reference(self->anm2, self->reference);
|
frame = anm2_frame_from_reference(self->anm2, self->reference);
|
||||||
@@ -2529,11 +2540,42 @@ static void _imgui_spritesheet_editor(Imgui* self)
|
|||||||
Texture* texture = spritesheet ? &spritesheet->texture : nullptr;
|
Texture* texture = spritesheet ? &spritesheet->texture : nullptr;
|
||||||
|
|
||||||
vec2 position = mousePos;
|
vec2 position = mousePos;
|
||||||
|
f32 step = isShift ? TOOL_STEP_MOD : TOOL_STEP;
|
||||||
|
|
||||||
|
if ((tool == TOOL_PAN && isMouseDown) || isMouseMiddleDown)
|
||||||
|
pan += vec2(mouseDelta.x, mouseDelta.y);
|
||||||
|
|
||||||
switch (tool)
|
switch (tool)
|
||||||
{
|
{
|
||||||
|
case TOOL_MOVE:
|
||||||
|
if (!texture || !frame) break;
|
||||||
|
|
||||||
|
if (isMouseClick || isLeft || isRight || isUp || isDown)
|
||||||
|
imgui_snapshot(self, IMGUI_ACTION_MOVE);
|
||||||
|
|
||||||
|
if (isMouseDown)
|
||||||
|
{
|
||||||
|
if (self->settings->editorIsGridSnap)
|
||||||
|
{
|
||||||
|
position.x = roundf(position.x / gridSize.x) * gridSize.x + gridOffset.x - (gridSize.x * 0.5f);
|
||||||
|
position.y = roundf(position.y / gridSize.y) * gridSize.y + gridOffset.y - (gridSize.y * 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
frame->pivot = position - frame->crop;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (isLeft) frame->pivot.x -= step;
|
||||||
|
if (isRight) frame->pivot.x += step;
|
||||||
|
if (isUp) frame->pivot.y -= step;
|
||||||
|
if (isDown) frame->pivot.y += step;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case TOOL_CROP:
|
case TOOL_CROP:
|
||||||
if (!frame || !texture) break;
|
if (!texture || !frame) break;
|
||||||
|
|
||||||
|
if (isMouseClick || isLeft || isRight || isUp || isDown)
|
||||||
|
imgui_snapshot(self, IMGUI_ACTION_MOVE);
|
||||||
|
|
||||||
if (self->settings->editorIsGridSnap)
|
if (self->settings->editorIsGridSnap)
|
||||||
{
|
{
|
||||||
@@ -2543,12 +2585,31 @@ static void _imgui_spritesheet_editor(Imgui* self)
|
|||||||
|
|
||||||
if (isMouseClick)
|
if (isMouseClick)
|
||||||
{
|
{
|
||||||
imgui_snapshot(self, IMGUI_ACTION_FRAME_CROP);
|
|
||||||
frame->crop = position;
|
frame->crop = position;
|
||||||
frame->size = ivec2(0,0);
|
frame->size = ivec2(0,0);
|
||||||
}
|
}
|
||||||
else if (isMouseDown)
|
else if (isMouseDown)
|
||||||
frame->size = position - frame->crop;
|
frame->size = position - frame->crop;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (isCtrl)
|
||||||
|
{
|
||||||
|
if (isLeft) frame->crop.x -= step;
|
||||||
|
if (isRight) frame->crop.x += step;
|
||||||
|
if (isUp) frame->crop.y -= step;
|
||||||
|
if (isDown) frame->crop.y += step;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (isLeft) frame->size.x -= step;
|
||||||
|
if (isRight) frame->size.x += step;
|
||||||
|
if (isUp) frame->size.y -= step;
|
||||||
|
if (isDown) frame->size.y += step;
|
||||||
|
}
|
||||||
|
|
||||||
|
frame->size.x = std::max({}, frame->size.x);
|
||||||
|
frame->size.y = std::max({}, frame->size.y);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case TOOL_DRAW:
|
case TOOL_DRAW:
|
||||||
case TOOL_ERASE:
|
case TOOL_ERASE:
|
||||||
@@ -2610,8 +2671,20 @@ static void _imgui_frame_properties(Imgui* self)
|
|||||||
_imgui_color_edit3(IMGUI_FRAME_PROPERTIES_COLOR_OFFSET.copy({!frame}), self, !frame ? dummy_value<vec3>() : frame->offsetRGB);
|
_imgui_color_edit3(IMGUI_FRAME_PROPERTIES_COLOR_OFFSET.copy({!frame}), self, !frame ? dummy_value<vec3>() : frame->offsetRGB);
|
||||||
_imgui_checkbox(IMGUI_FRAME_PROPERTIES_VISIBLE.copy({!frame}), self, !frame ? dummy_value<bool>() : frame->isVisible);
|
_imgui_checkbox(IMGUI_FRAME_PROPERTIES_VISIBLE.copy({!frame}), self, !frame ? dummy_value<bool>() : frame->isVisible);
|
||||||
_imgui_checkbox(IMGUI_FRAME_PROPERTIES_INTERPOLATED.copy({!frame}), self, !frame ? dummy_value<bool>() : frame->isInterpolated);
|
_imgui_checkbox(IMGUI_FRAME_PROPERTIES_INTERPOLATED.copy({!frame}), self, !frame ? dummy_value<bool>() : frame->isInterpolated);
|
||||||
|
_imgui_checkbox(IMGUI_FRAME_PROPERTIES_ROUND.copy({!frame}), self, self->settings->propertiesIsRound);
|
||||||
if (_imgui_button(IMGUI_FRAME_PROPERTIES_FLIP_X.copy({!frame}), self)) frame->scale.x = -frame->scale.x;
|
if (_imgui_button(IMGUI_FRAME_PROPERTIES_FLIP_X.copy({!frame}), self)) frame->scale.x = -frame->scale.x;
|
||||||
if (_imgui_button(IMGUI_FRAME_PROPERTIES_FLIP_Y.copy({!frame}), self)) frame->scale.y = -frame->scale.y;
|
if (_imgui_button(IMGUI_FRAME_PROPERTIES_FLIP_Y.copy({!frame}), self)) frame->scale.y = -frame->scale.y;
|
||||||
|
|
||||||
|
if (self->settings->propertiesIsRound && frame)
|
||||||
|
{
|
||||||
|
frame->position = glm::trunc(frame->position);
|
||||||
|
frame->pivot = glm::trunc(frame->pivot);
|
||||||
|
frame->crop = glm::trunc(frame->crop);
|
||||||
|
frame->scale = glm::trunc(frame->scale);
|
||||||
|
frame->rotation = glm::trunc(frame->rotation);
|
||||||
|
frame->tintRGBA = glm::trunc(frame->tintRGBA);
|
||||||
|
frame->offsetRGB = glm::trunc(frame->offsetRGB);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -2744,9 +2817,10 @@ void imgui_init
|
|||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
io.IniFilename = nullptr;
|
io.IniFilename = nullptr;
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
|
||||||
io.ConfigWindowsMoveFromTitleBarOnly = true;
|
io.ConfigWindowsMoveFromTitleBarOnly = true;
|
||||||
|
|
||||||
|
imgui_keyboard_nav_enable();
|
||||||
|
|
||||||
ImGui::LoadIniSettingsFromDisk(settings_path_get().c_str());
|
ImGui::LoadIniSettingsFromDisk(settings_path_get().c_str());
|
||||||
|
|
||||||
for (s32 i = 0; i < HOTKEY_COUNT; i++)
|
for (s32 i = 0; i < HOTKEY_COUNT; i++)
|
||||||
@@ -2779,6 +2853,8 @@ void imgui_update(Imgui* self)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
imgui_contextual_actions_enable(self);
|
||||||
|
|
||||||
if (self->pendingCursor != self->cursor)
|
if (self->pendingCursor != self->cursor)
|
||||||
{
|
{
|
||||||
SDL_SetCursor(SDL_CreateSystemCursor(self->pendingCursor));
|
SDL_SetCursor(SDL_CreateSystemCursor(self->pendingCursor));
|
||||||
|
147
src/imgui.h
147
src/imgui.h
@@ -64,13 +64,17 @@
|
|||||||
|
|
||||||
#define IMGUI_ACTION_FRAME_CROP "Frame Crop"
|
#define IMGUI_ACTION_FRAME_CROP "Frame Crop"
|
||||||
#define IMGUI_ACTION_FRAME_SWAP "Frame Swap"
|
#define IMGUI_ACTION_FRAME_SWAP "Frame Swap"
|
||||||
#define IMGUI_ACTION_FRAME_TRANSFORM "Frame Transform"
|
|
||||||
#define IMGUI_ACTION_ANIMATION_SWAP "Animation Swap"
|
#define IMGUI_ACTION_ANIMATION_SWAP "Animation Swap"
|
||||||
#define IMGUI_ACTION_TRIGGER_MOVE "Trigger AtFrame"
|
#define IMGUI_ACTION_TRIGGER_MOVE "Trigger AtFrame"
|
||||||
#define IMGUI_ACTION_FRAME_DELAY "Frame Delay"
|
#define IMGUI_ACTION_FRAME_DELAY "Frame Delay"
|
||||||
#define IMGUI_ACTION_MOVE_PLAYHEAD "Move Playhead"
|
#define IMGUI_ACTION_MOVE_PLAYHEAD "Move Playhead"
|
||||||
#define IMGUI_ACTION_DRAW "Draw"
|
#define IMGUI_ACTION_DRAW "Draw"
|
||||||
#define IMGUI_ACTION_ERASE "Erase"
|
#define IMGUI_ACTION_ERASE "Erase"
|
||||||
|
#define IMGUI_ACTION_MOVE "Move"
|
||||||
|
#define IMGUI_ACTION_SCALE "Scale"
|
||||||
|
#define IMGUI_ACTION_ROTATE "Rotate"
|
||||||
|
#define IMGUI_ACTION_CROP "Crop"
|
||||||
#define IMGUI_ACTION_RELOAD_SPRITESHEET "Reload Spritesheet(s)"
|
#define IMGUI_ACTION_RELOAD_SPRITESHEET "Reload Spritesheet(s)"
|
||||||
#define IMGUI_ACTION_REPLACE_SPRITESHEET "Replace Spritesheet"
|
#define IMGUI_ACTION_REPLACE_SPRITESHEET "Replace Spritesheet"
|
||||||
#define IMGUI_ACTION_OPEN_FILE "Open File"
|
#define IMGUI_ACTION_OPEN_FILE "Open File"
|
||||||
@@ -110,9 +114,10 @@
|
|||||||
#define IMGUI_SELECTABLE_INPUT_INT_FORMAT "#{}"
|
#define IMGUI_SELECTABLE_INPUT_INT_FORMAT "#{}"
|
||||||
#define IMGUI_TIMELINE_ANIMATION_NONE "Select an animation to show timeline..."
|
#define IMGUI_TIMELINE_ANIMATION_NONE "Select an animation to show timeline..."
|
||||||
#define IMGUI_HOTKEY_CHANGE "Input new hotkey..."
|
#define IMGUI_HOTKEY_CHANGE "Input new hotkey..."
|
||||||
#define IMGUI_LABEL_SHORTCUT_FORMAT "({})"
|
#define IMGUI_LABEL_HOTKEY_FORMAT " ({})"
|
||||||
#define IMGUI_TOOLTIP_SHORTCUT_FORMAT "\n(Shortcut: {})"
|
#define IMGUI_TOOLTIP_HOTKEY_FORMAT "\n(Hotkey: {})"
|
||||||
#define IMGUI_INVISIBLE_FORMAT "## {}"
|
#define IMGUI_INVISIBLE_FORMAT "## {}"
|
||||||
|
#define IMGUI_RENDERING_FFMPEG_INFO_THRESHOLD 0.95f
|
||||||
|
|
||||||
#define IMGUI_TRIGGERS_FONT_SCALE 2.0
|
#define IMGUI_TRIGGERS_FONT_SCALE 2.0
|
||||||
|
|
||||||
@@ -222,7 +227,7 @@ static void imgui_log_push(Imgui* self, const std::string& text)
|
|||||||
log_imgui(text);
|
log_imgui(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void imgui_file_new(Imgui* self)
|
static inline void imgui_anm2_new(Imgui* self)
|
||||||
{
|
{
|
||||||
anm2_reference_clear(self->reference);
|
anm2_reference_clear(self->reference);
|
||||||
anm2_free(self->anm2);
|
anm2_free(self->anm2);
|
||||||
@@ -245,6 +250,14 @@ static inline void imgui_file_save(Imgui* self)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void imgui_file_new(Imgui* self)
|
||||||
|
{
|
||||||
|
std::string path = self->anm2->path;
|
||||||
|
imgui_anm2_new(self);
|
||||||
|
self->anm2->path = path;
|
||||||
|
imgui_file_save(self);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void imgui_file_save_as(Imgui* self)
|
static inline void imgui_file_save_as(Imgui* self)
|
||||||
{
|
{
|
||||||
dialog_anm2_save(self->dialog);
|
dialog_anm2_save(self->dialog);
|
||||||
@@ -520,10 +533,17 @@ static inline ImGuiKeyChord imgui_chord_from_string_get(const std::string& str)
|
|||||||
return chord;
|
return chord;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void imgui_keyboard_nav_enable(void) { ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; }
|
||||||
static void imgui_contextual_actions_enable(Imgui* self) { self->isContextualActionsEnabled = true; }
|
static inline void imgui_keyboard_nav_disable(void) { ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_NavEnableKeyboard; }
|
||||||
static void imgui_contextual_actions_disable(Imgui* self){ self->isContextualActionsEnabled = false; }
|
static inline void imgui_contextual_actions_enable(Imgui* self) { self->isContextualActionsEnabled = true; }
|
||||||
|
static inline void imgui_contextual_actions_disable(Imgui* self){ self->isContextualActionsEnabled = false; }
|
||||||
static inline bool imgui_is_popup_open(const std::string& label) { return ImGui::IsPopupOpen(label.c_str()); }
|
static inline bool imgui_is_popup_open(const std::string& label) { return ImGui::IsPopupOpen(label.c_str()); }
|
||||||
|
|
||||||
|
static inline bool imgui_is_any_popup_open(void)
|
||||||
|
{
|
||||||
|
return ImGui::IsPopupOpen(nullptr, ImGuiPopupFlags_AnyPopupId);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void imgui_open_popup(const std::string& label) { ImGui::OpenPopup(label.c_str()); }
|
static inline void imgui_open_popup(const std::string& label) { ImGui::OpenPopup(label.c_str()); }
|
||||||
static inline void imgui_pending_popup_process(Imgui* self)
|
static inline void imgui_pending_popup_process(Imgui* self)
|
||||||
{
|
{
|
||||||
@@ -656,7 +676,7 @@ struct ImguiItem
|
|||||||
bool isSelected = false;
|
bool isSelected = false;
|
||||||
bool isUseItemActivated = false;
|
bool isUseItemActivated = false;
|
||||||
bool isSizeToText = false;
|
bool isSizeToText = false;
|
||||||
bool isShortcutInLabel = false;
|
bool isHotkeyInLabel = false;
|
||||||
bool isSameLine = false;
|
bool isSameLine = false;
|
||||||
bool isSeparator = false;
|
bool isSeparator = false;
|
||||||
s32 id = 0;
|
s32 id = 0;
|
||||||
@@ -673,6 +693,23 @@ struct ImguiItem
|
|||||||
s32 windowFlags{};
|
s32 windowFlags{};
|
||||||
s32 rowCount = 0;
|
s32 rowCount = 0;
|
||||||
|
|
||||||
|
bool is_border() const { return border != 0; }
|
||||||
|
bool is_row() const { return rowCount != 0; }
|
||||||
|
bool is_hotkey() const { return hotkey != HOTKEY_NONE; }
|
||||||
|
bool is_chord() const { return chord != IMGUI_CHORD_NONE || is_hotkey(); }
|
||||||
|
bool is_drag_drop() const { return !dragDrop.empty(); }
|
||||||
|
bool is_focus_window() const { return !focusWindow.empty(); }
|
||||||
|
bool is_popup() const { return !popup.empty(); }
|
||||||
|
bool is_function() const { return function; }
|
||||||
|
bool is_size() const { return size != ImVec2(); }
|
||||||
|
bool is_popup_size() const { return popupSize != ImVec2(); }
|
||||||
|
bool is_tooltip() const { return !tooltip.empty(); }
|
||||||
|
bool is_undoable() const { return !snapshotAction.empty(); }
|
||||||
|
bool is_mnemonic() const { return mnemonicKey != ImGuiKey_None; }
|
||||||
|
bool is_range() const { return min != 0 || max != 0; }
|
||||||
|
const char* drag_drop_get() const { return dragDrop.c_str(); }
|
||||||
|
const char* text_get() const { return text.c_str(); }
|
||||||
|
|
||||||
void construct()
|
void construct()
|
||||||
{
|
{
|
||||||
static s32 idNew = 0;
|
static s32 idNew = 0;
|
||||||
@@ -728,24 +765,21 @@ struct ImguiItem
|
|||||||
return chord;
|
return chord;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_border() const { return border != 0; }
|
std::string label_get() const
|
||||||
bool is_row() const { return rowCount != 0; }
|
{
|
||||||
bool is_hotkey() const { return hotkey != HOTKEY_NONE; }
|
std::string newLabel = label;
|
||||||
bool is_chord() const { return chord != IMGUI_CHORD_NONE || is_hotkey(); }
|
if (isHotkeyInLabel)
|
||||||
bool is_drag_drop() const { return !dragDrop.empty(); }
|
newLabel += std::format(IMGUI_LABEL_HOTKEY_FORMAT, imgui_string_from_chord_get(chord_get()));
|
||||||
bool is_focus_window() const { return !focusWindow.empty(); }
|
return newLabel;
|
||||||
bool is_popup() const { return !popup.empty(); }
|
}
|
||||||
bool is_function() const { return function; }
|
|
||||||
bool is_size() const { return size != ImVec2(); }
|
std::string tooltip_get() const
|
||||||
bool is_popup_size() const { return popupSize != ImVec2(); }
|
{
|
||||||
bool is_tooltip() const { return !tooltip.empty(); }
|
std::string newTooltip = tooltip;
|
||||||
bool is_undoable() const { return !snapshotAction.empty(); }
|
if (is_chord())
|
||||||
bool is_mnemonic() const { return mnemonicKey != ImGuiKey_None; }
|
newTooltip += std::format(IMGUI_TOOLTIP_HOTKEY_FORMAT, imgui_string_from_chord_get(chord_get()));
|
||||||
bool is_range() const { return min != 0 || max != 0; }
|
return newTooltip;
|
||||||
const char* label_get() const { return label.c_str(); }
|
}
|
||||||
const char* drag_drop_get() const { return dragDrop.c_str(); }
|
|
||||||
const char* tooltip_get() const { return tooltip.c_str(); }
|
|
||||||
const char* text_get() const { return text.c_str(); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IMGUI_ITEM(NAME, ...) const inline ImguiItem NAME = []{ ImguiItem self; __VA_ARGS__; self.construct(); return self; }()
|
#define IMGUI_ITEM(NAME, ...) const inline ImguiItem NAME = []{ ImguiItem self; __VA_ARGS__; self.construct(); return self; }()
|
||||||
@@ -797,7 +831,7 @@ IMGUI_ITEM(IMGUI_NEW,
|
|||||||
self.function = imgui_file_new,
|
self.function = imgui_file_new,
|
||||||
self.hotkey = HOTKEY_NEW,
|
self.hotkey = HOTKEY_NEW,
|
||||||
self.isSizeToText = true,
|
self.isSizeToText = true,
|
||||||
self.isShortcutInLabel = true
|
self.isHotkeyInLabel = true
|
||||||
);
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_OPEN,
|
IMGUI_ITEM(IMGUI_OPEN,
|
||||||
@@ -806,7 +840,7 @@ IMGUI_ITEM(IMGUI_OPEN,
|
|||||||
self.function = imgui_file_open,
|
self.function = imgui_file_open,
|
||||||
self.hotkey = HOTKEY_OPEN,
|
self.hotkey = HOTKEY_OPEN,
|
||||||
self.isSizeToText = true,
|
self.isSizeToText = true,
|
||||||
self.isShortcutInLabel = true
|
self.isHotkeyInLabel = true
|
||||||
);
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_SAVE,
|
IMGUI_ITEM(IMGUI_SAVE,
|
||||||
@@ -815,7 +849,7 @@ IMGUI_ITEM(IMGUI_SAVE,
|
|||||||
self.function = imgui_file_save,
|
self.function = imgui_file_save,
|
||||||
self.hotkey = HOTKEY_SAVE,
|
self.hotkey = HOTKEY_SAVE,
|
||||||
self.isSizeToText = true,
|
self.isSizeToText = true,
|
||||||
self.isShortcutInLabel = true
|
self.isHotkeyInLabel = true
|
||||||
);
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_SAVE_AS,
|
IMGUI_ITEM(IMGUI_SAVE_AS,
|
||||||
@@ -824,7 +858,7 @@ IMGUI_ITEM(IMGUI_SAVE_AS,
|
|||||||
self.function = imgui_file_save_as,
|
self.function = imgui_file_save_as,
|
||||||
self.hotkey = HOTKEY_SAVE_AS,
|
self.hotkey = HOTKEY_SAVE_AS,
|
||||||
self.isSizeToText = true,
|
self.isSizeToText = true,
|
||||||
self.isShortcutInLabel = true
|
self.isHotkeyInLabel = true
|
||||||
);
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_EXPLORE_ANM2_LOCATION,
|
IMGUI_ITEM(IMGUI_EXPLORE_ANM2_LOCATION,
|
||||||
@@ -841,7 +875,7 @@ IMGUI_ITEM(IMGUI_EXIT,
|
|||||||
self.function = imgui_quit,
|
self.function = imgui_quit,
|
||||||
self.hotkey = HOTKEY_EXIT,
|
self.hotkey = HOTKEY_EXIT,
|
||||||
self.isSizeToText = true,
|
self.isSizeToText = true,
|
||||||
self.isShortcutInLabel = true
|
self.isHotkeyInLabel = true
|
||||||
);
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_EXIT_CONFIRMATION,
|
IMGUI_ITEM(IMGUI_EXIT_CONFIRMATION,
|
||||||
@@ -1042,7 +1076,7 @@ IMGUI_ITEM(IMGUI_CHANGE_ALL_FRAME_PROPERTIES_CANCEL,
|
|||||||
);
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_SCALE_ANM2,
|
IMGUI_ITEM(IMGUI_SCALE_ANM2,
|
||||||
self.label = "&Scale Anm2",
|
self.label = "S&cale Anm2",
|
||||||
self.tooltip = "Scale up all size and position-related frame properties in the anm2.",
|
self.tooltip = "Scale up all size and position-related frame properties in the anm2.",
|
||||||
self.popup = "Scale Anm2",
|
self.popup = "Scale Anm2",
|
||||||
self.popupType = IMGUI_POPUP_CENTER_WINDOW,
|
self.popupType = IMGUI_POPUP_CENTER_WINDOW,
|
||||||
@@ -1135,6 +1169,13 @@ IMGUI_ITEM(IMGUI_RENDER_ANIMATION_CONFIRM,
|
|||||||
self.rowCount = IMGUI_OPTION_POPUP_ROW_COUNT
|
self.rowCount = IMGUI_OPTION_POPUP_ROW_COUNT
|
||||||
);
|
);
|
||||||
|
|
||||||
|
IMGUI_ITEM(IMGUI_RENDERING_ANIMATION_CHILD,
|
||||||
|
self.label = "##Rendering Child",
|
||||||
|
self.size = {400.0f, 65.0f},
|
||||||
|
self.flags = true
|
||||||
|
);
|
||||||
|
|
||||||
|
IMGUI_ITEM(IMGUI_RENDERING_ANIMATION_INFO, self.label = "Recording frames. Once done, the program may halt\nas FFmpeg renders the animation. Please be patient!");
|
||||||
IMGUI_ITEM(IMGUI_RENDERING_ANIMATION_CANCEL,
|
IMGUI_ITEM(IMGUI_RENDERING_ANIMATION_CANCEL,
|
||||||
self.label = "Cancel",
|
self.label = "Cancel",
|
||||||
self.tooltip = "Cancel rendering the animation.",
|
self.tooltip = "Cancel rendering the animation.",
|
||||||
@@ -1558,10 +1599,10 @@ IMGUI_ITEM(IMGUI_CANVAS_PIVOTS,
|
|||||||
self.value = SETTINGS_PREVIEW_IS_PIVOTS_DEFAULT
|
self.value = SETTINGS_PREVIEW_IS_PIVOTS_DEFAULT
|
||||||
);
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_CANVAS_TARGETS,
|
IMGUI_ITEM(IMGUI_CANVAS_ICONS,
|
||||||
self.label = "Targets",
|
self.label = "Icons",
|
||||||
self.tooltip = "Toggles drawing the targets (the colored root/null icons).",
|
self.tooltip = "Toggles drawing the the colored root/null icons.",
|
||||||
self.value = SETTINGS_PREVIEW_IS_TARGETS_DEFAULT
|
self.value = SETTINGS_PREVIEW_IS_ICONS_DEFAULT
|
||||||
);
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_CANVAS_ALT_ICONS,
|
IMGUI_ITEM(IMGUI_CANVAS_ALT_ICONS,
|
||||||
@@ -1581,12 +1622,22 @@ IMGUI_ITEM(IMGUI_ANIMATION_PREVIEW,
|
|||||||
self.flags = ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse
|
self.flags = ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#define IMGUI_ANIMATION_PREVIEW_VIEW_ROW_COUNT 2
|
||||||
IMGUI_ITEM(IMGUI_ANIMATION_PREVIEW_CENTER_VIEW,
|
IMGUI_ITEM(IMGUI_ANIMATION_PREVIEW_CENTER_VIEW,
|
||||||
self.label = "Center View",
|
self.label = "Center View",
|
||||||
self.tooltip = "Centers the current view on the animation preview.",
|
self.tooltip = "Centers the current view on the animation preview.",
|
||||||
self.hotkey = HOTKEY_CENTER_VIEW,
|
self.hotkey = HOTKEY_CENTER_VIEW,
|
||||||
self.focusWindow = IMGUI_ANIMATION_PREVIEW.label,
|
self.focusWindow = IMGUI_ANIMATION_PREVIEW.label,
|
||||||
self.size = {-FLT_MIN, 0}
|
self.rowCount = IMGUI_ANIMATION_PREVIEW_VIEW_ROW_COUNT,
|
||||||
|
self.isSameLine = true
|
||||||
|
);
|
||||||
|
|
||||||
|
IMGUI_ITEM(IMGUI_ANIMATION_PREVIEW_FIT,
|
||||||
|
self.label = "Fit",
|
||||||
|
self.tooltip = "Adjust the view/pan based on the size of the animation, to fit the canvas' size.",
|
||||||
|
self.hotkey = HOTKEY_FIT,
|
||||||
|
self.focusWindow = IMGUI_ANIMATION_PREVIEW.label,
|
||||||
|
self.rowCount = IMGUI_ANIMATION_PREVIEW_VIEW_ROW_COUNT
|
||||||
);
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_SPRITESHEET_EDITOR,
|
IMGUI_ITEM(IMGUI_SPRITESHEET_EDITOR,
|
||||||
@@ -1672,12 +1723,12 @@ IMGUI_ITEM(IMGUI_FRAME_PROPERTIES_COLOR_OFFSET,
|
|||||||
self.value = 0
|
self.value = 0
|
||||||
);
|
);
|
||||||
|
|
||||||
const ImVec2 IMGUI_FRAME_PROPERTIES_FLIP_BUTTON_SIZE = {75, 0};
|
#define IMGUI_FRAME_PROPERTIES_FLIP_ROW_COUNT 2
|
||||||
IMGUI_ITEM(IMGUI_FRAME_PROPERTIES_FLIP_X,
|
IMGUI_ITEM(IMGUI_FRAME_PROPERTIES_FLIP_X,
|
||||||
self.label = "Flip X",
|
self.label = "Flip X",
|
||||||
self.tooltip = "Change the sign of the X scale, to cheat flipping the layer horizontally.\n(Anm2 doesn't support flipping directly.)",
|
self.tooltip = "Change the sign of the X scale, to cheat flipping the layer horizontally.\n(Anm2 doesn't support flipping directly.)",
|
||||||
self.snapshotAction = "Frame Flip X",
|
self.snapshotAction = "Frame Flip X",
|
||||||
self.size = IMGUI_FRAME_PROPERTIES_FLIP_BUTTON_SIZE,
|
self.rowCount = IMGUI_FRAME_PROPERTIES_FLIP_ROW_COUNT,
|
||||||
self.isSameLine = true
|
self.isSameLine = true
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1685,7 +1736,7 @@ IMGUI_ITEM(IMGUI_FRAME_PROPERTIES_FLIP_Y,
|
|||||||
self.label = "Flip Y",
|
self.label = "Flip Y",
|
||||||
self.tooltip = "Change the sign of the Y scale, to cheat flipping the layer vertically.\n(Anm2 doesn't support flipping directly.)",
|
self.tooltip = "Change the sign of the Y scale, to cheat flipping the layer vertically.\n(Anm2 doesn't support flipping directly.)",
|
||||||
self.snapshotAction = "Frame Flip Y",
|
self.snapshotAction = "Frame Flip Y",
|
||||||
self.size = IMGUI_FRAME_PROPERTIES_FLIP_BUTTON_SIZE
|
self.rowCount = IMGUI_FRAME_PROPERTIES_FLIP_ROW_COUNT
|
||||||
);
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_FRAME_PROPERTIES_VISIBLE,
|
IMGUI_ITEM(IMGUI_FRAME_PROPERTIES_VISIBLE,
|
||||||
@@ -1700,9 +1751,16 @@ IMGUI_ITEM(IMGUI_FRAME_PROPERTIES_INTERPOLATED,
|
|||||||
self.label = "Interpolation",
|
self.label = "Interpolation",
|
||||||
self.tooltip = "Toggles the interpolation of the selected frame.",
|
self.tooltip = "Toggles the interpolation of the selected frame.",
|
||||||
self.snapshotAction = "Frame Interpolation",
|
self.snapshotAction = "Frame Interpolation",
|
||||||
|
self.isSameLine = true,
|
||||||
self.value = true
|
self.value = true
|
||||||
);
|
);
|
||||||
|
|
||||||
|
IMGUI_ITEM(IMGUI_FRAME_PROPERTIES_ROUND,
|
||||||
|
self.label = "Round",
|
||||||
|
self.tooltip = "Values will be rounded to the nearest integer.",
|
||||||
|
self.value = SETTINGS_PROPERTIES_IS_ROUND_DEFAULT
|
||||||
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_FRAME_PROPERTIES_EVENT,
|
IMGUI_ITEM(IMGUI_FRAME_PROPERTIES_EVENT,
|
||||||
self.label = "Event",
|
self.label = "Event",
|
||||||
self.tooltip = "Change the event the trigger uses.",
|
self.tooltip = "Change the event the trigger uses.",
|
||||||
@@ -1727,7 +1785,7 @@ IMGUI_ITEM(IMGUI_TOOL_PAN,
|
|||||||
|
|
||||||
IMGUI_ITEM(IMGUI_TOOL_MOVE,
|
IMGUI_ITEM(IMGUI_TOOL_MOVE,
|
||||||
self.label = "## Move",
|
self.label = "## Move",
|
||||||
self.tooltip = "Use the move tool.\nWill move the selected item as the cursor is dragged, or directional keys are pressed.\n(Animation Preview only.)",
|
self.tooltip = "Use the move tool.\nWhen in animation preview, will move the position of the frame.\nWhen in spritesheet editor, will move the pivot instead.\nUse mouse or directional keys to change the value.",
|
||||||
self.function = imgui_tool_move_set,
|
self.function = imgui_tool_move_set,
|
||||||
self.hotkey = HOTKEY_MOVE,
|
self.hotkey = HOTKEY_MOVE,
|
||||||
self.atlas = ATLAS_MOVE
|
self.atlas = ATLAS_MOVE
|
||||||
@@ -1751,7 +1809,7 @@ IMGUI_ITEM(IMGUI_TOOL_SCALE,
|
|||||||
|
|
||||||
IMGUI_ITEM(IMGUI_TOOL_CROP,
|
IMGUI_ITEM(IMGUI_TOOL_CROP,
|
||||||
self.label = "## Crop",
|
self.label = "## Crop",
|
||||||
self.tooltip = "Use the crop tool.\nWill produce a crop rectangle based on how the cursor is dragged.\n(Spritesheet Editor only.)",
|
self.tooltip = "Use the crop tool.\nWill produce a crop rectangle based on how the cursor is dragged.\nAlternatively, you can use the arrow keys and Ctrl/Shift to move the size/position, respectively.\n(Spritesheet Editor only.)",
|
||||||
self.function = imgui_tool_crop_set,
|
self.function = imgui_tool_crop_set,
|
||||||
self.hotkey = HOTKEY_CROP,
|
self.hotkey = HOTKEY_CROP,
|
||||||
self.atlas = ATLAS_CROP
|
self.atlas = ATLAS_CROP
|
||||||
@@ -2082,7 +2140,8 @@ IMGUI_ITEM(IMGUI_TIMELINE_REMOVE_ITEM,
|
|||||||
self.label = "Remove",
|
self.label = "Remove",
|
||||||
self.tooltip = "Removes the selected item (layer or null) from the animation.",
|
self.tooltip = "Removes the selected item (layer or null) from the animation.",
|
||||||
self.snapshotAction = "Remove Item",
|
self.snapshotAction = "Remove Item",
|
||||||
self.focusWindow = IMGUI_TIMELINE.label,
|
self.chord = ImGuiKey_Delete,
|
||||||
|
self.focusWindow = IMGUI_TIMELINE_ITEMS_CHILD.label,
|
||||||
self.rowCount = IMGUI_TIMELINE_FOOTER_ITEM_CHILD_ITEM_COUNT
|
self.rowCount = IMGUI_TIMELINE_FOOTER_ITEM_CHILD_ITEM_COUNT
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -2221,7 +2280,7 @@ IMGUI_ITEM(IMGUI_ONIONSKIN_ENABLED,
|
|||||||
self.isSeparator = true
|
self.isSeparator = true
|
||||||
);
|
);
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_ONIONSKIN_BEFORE, self.label = "-- Before-- ");
|
IMGUI_ITEM(IMGUI_ONIONSKIN_BEFORE, self.label = "-- Before -- ");
|
||||||
IMGUI_ITEM(IMGUI_ONIONSKIN_AFTER, self.label = "-- After -- ");
|
IMGUI_ITEM(IMGUI_ONIONSKIN_AFTER, self.label = "-- After -- ");
|
||||||
|
|
||||||
IMGUI_ITEM(IMGUI_ONIONSKIN_COUNT,
|
IMGUI_ITEM(IMGUI_ONIONSKIN_COUNT,
|
||||||
|
16
src/main.cpp
16
src/main.cpp
@@ -4,7 +4,7 @@ static bool _anm2_rescale(const std::string& file, f32 scale)
|
|||||||
{
|
{
|
||||||
Anm2 anm2;
|
Anm2 anm2;
|
||||||
|
|
||||||
if (!anm2_deserialize(&anm2, file)) return false;
|
if (!anm2_deserialize(&anm2, file, false)) return false;
|
||||||
anm2_scale(&anm2, scale);
|
anm2_scale(&anm2, scale);
|
||||||
return anm2_serialize(&anm2, file);
|
return anm2_serialize(&anm2, file);
|
||||||
}
|
}
|
||||||
@@ -35,9 +35,19 @@ main(s32 argc, char* argv[])
|
|||||||
|
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
else if (std::string(argv[1]) == ARGUMENT_TEST && argv[2])
|
||||||
|
{
|
||||||
|
if (anm2_deserialize(&state.anm2, std::string(argv[2]), false)) return EXIT_SUCCESS;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
else if (std::string(argv[1]) == ARGUMENT_TEST_GL && argv[2])
|
||||||
|
{
|
||||||
|
if (!sdl_init(&state, true)) return EXIT_FAILURE;
|
||||||
|
if (anm2_deserialize(&state.anm2, std::string(argv[2]))) return EXIT_SUCCESS;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
if (argv[1])
|
if (argv[1]) state.argument = argv[1];
|
||||||
state.argument = argv[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init(&state);
|
init(&state);
|
||||||
|
@@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL_main.h>
|
#include <SDL3/SDL_main.h>
|
||||||
|
|
||||||
|
#define ARGUMENT_TEST "--test"
|
||||||
|
#define ARGUMENT_TEST_GL "--test-gl"
|
||||||
|
|
||||||
#define ARGUMENT_RESCALE "--rescale"
|
#define ARGUMENT_RESCALE "--rescale"
|
||||||
#define ARGUMENT_RESCALE_ARGUMENT_ERROR "--rescale: specify both anm2 and scale arguments"
|
#define ARGUMENT_RESCALE_ARGUMENT_ERROR "--rescale: specify both anm2 and scale arguments"
|
||||||
#define ARGUMENT_RESCALE_ANM2_ERROR "Unable to rescale anm2 {} by value {}. Make sure the file is valid."
|
#define ARGUMENT_RESCALE_ANM2_ERROR "Unable to rescale anm2 {} by value {}. Make sure the file is valid."
|
||||||
|
@@ -105,7 +105,7 @@ void preview_draw(Preview* self)
|
|||||||
|
|
||||||
auto root_draw = [&](Anm2Frame root, vec3 colorOffset = {}, f32 alphaOffset = {}, bool isOnionskin = {})
|
auto root_draw = [&](Anm2Frame root, vec3 colorOffset = {}, f32 alphaOffset = {}, bool isOnionskin = {})
|
||||||
{
|
{
|
||||||
mat4 model = canvas_model_get(PREVIEW_TARGET_SIZE, root.position, PREVIEW_TARGET_SIZE * 0.5f, PERCENT_TO_UNIT(root.scale), root.rotation);
|
mat4 model = quad_model_get(PREVIEW_TARGET_SIZE, root.position, PREVIEW_TARGET_SIZE * 0.5f, PERCENT_TO_UNIT(root.scale), root.rotation);
|
||||||
mat4 rootTransform = transform * model;
|
mat4 rootTransform = transform * model;
|
||||||
vec4 color = isOnionskin ? vec4(colorOffset, 1.0f - alphaOffset) : PREVIEW_ROOT_COLOR;
|
vec4 color = isOnionskin ? vec4(colorOffset, 1.0f - alphaOffset) : PREVIEW_ROOT_COLOR;
|
||||||
AtlasType atlas = self->settings->previewIsAltIcons ? ATLAS_TARGET_ALT : ATLAS_TARGET;
|
AtlasType atlas = self->settings->previewIsAltIcons ? ATLAS_TARGET_ALT : ATLAS_TARGET;
|
||||||
@@ -122,7 +122,7 @@ void preview_draw(Preview* self)
|
|||||||
anm2_frame_from_time(self->anm2, &frame, Anm2Reference{animationID, ANM2_LAYER, id}, time);
|
anm2_frame_from_time(self->anm2, &frame, Anm2Reference{animationID, ANM2_LAYER, id}, time);
|
||||||
if (!frame.isVisible) return;
|
if (!frame.isVisible) return;
|
||||||
|
|
||||||
mat4 model = canvas_model_get(frame.size, frame.position, frame.pivot, PERCENT_TO_UNIT(frame.scale), frame.rotation);
|
mat4 model = quad_model_get(frame.size, frame.position, frame.pivot, PERCENT_TO_UNIT(frame.scale), frame.rotation);
|
||||||
mat4 layerTransform = transform * (rootModel * model);
|
mat4 layerTransform = transform * (rootModel * model);
|
||||||
vec3 frameColorOffset = frame.offsetRGB + colorOffset;
|
vec3 frameColorOffset = frame.offsetRGB + colorOffset;
|
||||||
vec4 frameTint = frame.tintRGBA;
|
vec4 frameTint = frame.tintRGBA;
|
||||||
@@ -149,7 +149,7 @@ void preview_draw(Preview* self)
|
|||||||
{
|
{
|
||||||
vec4 pivotColor = isOnionskin ? vec4(colorOffset, 1.0f - alphaOffset) : PREVIEW_PIVOT_COLOR;
|
vec4 pivotColor = isOnionskin ? vec4(colorOffset, 1.0f - alphaOffset) : PREVIEW_PIVOT_COLOR;
|
||||||
f32 vertices[] = ATLAS_UV_VERTICES(ATLAS_PIVOT);
|
f32 vertices[] = ATLAS_UV_VERTICES(ATLAS_PIVOT);
|
||||||
mat4 pivotModel = canvas_model_get(CANVAS_PIVOT_SIZE, frame.position, CANVAS_PIVOT_SIZE * 0.5f, PERCENT_TO_UNIT(frame.scale), frame.rotation);
|
mat4 pivotModel = quad_model_get(CANVAS_PIVOT_SIZE, frame.position, CANVAS_PIVOT_SIZE * 0.5f, PERCENT_TO_UNIT(frame.scale), frame.rotation);
|
||||||
mat4 pivotTransform = transform * (rootModel * pivotModel);
|
mat4 pivotTransform = transform * (rootModel * pivotModel);
|
||||||
canvas_texture_draw(&self->canvas, shaderTexture, self->resources->atlas.id, pivotTransform, vertices, pivotColor);
|
canvas_texture_draw(&self->canvas, shaderTexture, self->resources->atlas.id, pivotTransform, vertices, pivotColor);
|
||||||
}
|
}
|
||||||
@@ -173,7 +173,7 @@ void preview_draw(Preview* self)
|
|||||||
vec2 size = null.isShowRect ? CANVAS_PIVOT_SIZE : PREVIEW_TARGET_SIZE;
|
vec2 size = null.isShowRect ? CANVAS_PIVOT_SIZE : PREVIEW_TARGET_SIZE;
|
||||||
AtlasType atlas = null.isShowRect ? ATLAS_SQUARE : self->settings->previewIsAltIcons ? ATLAS_TARGET_ALT : ATLAS_TARGET;
|
AtlasType atlas = null.isShowRect ? ATLAS_SQUARE : self->settings->previewIsAltIcons ? ATLAS_TARGET_ALT : ATLAS_TARGET;
|
||||||
|
|
||||||
mat4 model = canvas_model_get(size, frame.position, size * 0.5f, PERCENT_TO_UNIT(frame.scale), frame.rotation);
|
mat4 model = quad_model_get(size, frame.position, size * 0.5f, PERCENT_TO_UNIT(frame.scale), frame.rotation);
|
||||||
mat4 nullTransform = transform * (rootModel * model);
|
mat4 nullTransform = transform * (rootModel * model);
|
||||||
|
|
||||||
f32 vertices[] = ATLAS_UV_VERTICES(atlas);
|
f32 vertices[] = ATLAS_UV_VERTICES(atlas);
|
||||||
@@ -182,7 +182,7 @@ void preview_draw(Preview* self)
|
|||||||
|
|
||||||
if (null.isShowRect)
|
if (null.isShowRect)
|
||||||
{
|
{
|
||||||
mat4 rectModel = canvas_model_get(PREVIEW_NULL_RECT_SIZE, frame.position, PREVIEW_NULL_RECT_SIZE * 0.5f, PERCENT_TO_UNIT(frame.scale), frame.rotation);
|
mat4 rectModel = quad_model_get(PREVIEW_NULL_RECT_SIZE, frame.position, PREVIEW_NULL_RECT_SIZE * 0.5f, PERCENT_TO_UNIT(frame.scale), frame.rotation);
|
||||||
mat4 rectTransform = transform * (rootModel * rectModel);
|
mat4 rectTransform = transform * (rootModel * rectModel);
|
||||||
canvas_rect_draw(&self->canvas, shaderLine, rectTransform, color);
|
canvas_rect_draw(&self->canvas, shaderLine, rectTransform, color);
|
||||||
}
|
}
|
||||||
@@ -194,15 +194,15 @@ void preview_draw(Preview* self)
|
|||||||
anm2_frame_from_time(self->anm2, &root, Anm2Reference{animationID, ANM2_ROOT}, time);
|
anm2_frame_from_time(self->anm2, &root, Anm2Reference{animationID, ANM2_ROOT}, time);
|
||||||
|
|
||||||
mat4 rootModel = self->settings->previewIsRootTransform ?
|
mat4 rootModel = self->settings->previewIsRootTransform ?
|
||||||
canvas_parent_model_get(root.position, {}, PERCENT_TO_UNIT(root.scale), root.rotation) : mat4(1.0f);
|
quad_model_parent_get(root.position, {}, PERCENT_TO_UNIT(root.scale), root.rotation) : mat4(1.0f);
|
||||||
|
|
||||||
if (self->settings->previewIsTargets && animation->rootAnimation.isVisible && root.isVisible)
|
if (self->settings->previewIsIcons && animation->rootAnimation.isVisible && root.isVisible)
|
||||||
root_draw(root, colorOffset, alphaOffset, isOnionskin);
|
root_draw(root, colorOffset, alphaOffset, isOnionskin);
|
||||||
|
|
||||||
for (auto [i, id] : self->anm2->layerMap)
|
for (auto [i, id] : self->anm2->layerMap)
|
||||||
layer_draw(rootModel, id, time, colorOffset, alphaOffset, isOnionskin);
|
layer_draw(rootModel, id, time, colorOffset, alphaOffset, isOnionskin);
|
||||||
|
|
||||||
if (self->settings->previewIsTargets)
|
if (self->settings->previewIsIcons)
|
||||||
for (auto& [id, _] : animation->nullAnimations)
|
for (auto& [id, _] : animation->nullAnimations)
|
||||||
null_draw(rootModel, id, time, colorOffset, alphaOffset, isOnionskin);
|
null_draw(rootModel, id, time, colorOffset, alphaOffset, isOnionskin);
|
||||||
};
|
};
|
||||||
|
@@ -42,8 +42,6 @@ struct Preview
|
|||||||
f32 time{};
|
f32 time{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void preview_init(Preview* self, Anm2* anm2, Anm2Reference* reference, Resources* resources, Settings* settings);
|
void preview_init(Preview* self, Anm2* anm2, Anm2Reference* reference, Resources* resources, Settings* settings);
|
||||||
void preview_draw(Preview* self);
|
void preview_draw(Preview* self);
|
||||||
void preview_tick(Preview* self);
|
void preview_tick(Preview* self);
|
||||||
|
@@ -20,12 +20,19 @@
|
|||||||
#define SETTINGS_PATH "settings.ini"
|
#define SETTINGS_PATH "settings.ini"
|
||||||
#define SETTINGS_TEMPORARY_EXTENSION ".tmp"
|
#define SETTINGS_TEMPORARY_EXTENSION ".tmp"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define SETTINGS_FFMPEG_PATH_VALUE_DEFAULT "C:\\ffmpeg\\bin\\ffmpeg.exe"
|
||||||
|
#else
|
||||||
|
#define SETTINGS_FFMPEG_PATH_VALUE_DEFAULT "/usr/bin/ffmpeg"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define SETTINGS_LIST \
|
#define SETTINGS_LIST \
|
||||||
/* name, symbol, type, defaultValue */ \
|
/* name, symbol, type, defaultValue */ \
|
||||||
X(windowSize, WINDOW_SIZE, TYPE_IVEC2_WH, {1280, 720}) \
|
X(windowSize, WINDOW_SIZE, TYPE_IVEC2_WH, {1280, 720}) \
|
||||||
X(isVsync, IS_VSYNC, TYPE_BOOL, true) \
|
X(isVsync, IS_VSYNC, TYPE_BOOL, true) \
|
||||||
\
|
\
|
||||||
X(hotkeyCenterView, HOTKEY_CENTER_VIEW, TYPE_STRING, "Home") \
|
X(hotkeyCenterView, HOTKEY_CENTER_VIEW, TYPE_STRING, "Home") \
|
||||||
|
X(hotkeyFit, HOTKEY_FIT, TYPE_STRING, "F") \
|
||||||
X(hotkeyZoomIn, HOTKEY_ZOOM_IN, TYPE_STRING, "Ctrl++") \
|
X(hotkeyZoomIn, HOTKEY_ZOOM_IN, TYPE_STRING, "Ctrl++") \
|
||||||
X(hotkeyZoomOut, HOTKEY_ZOOM_OUT, TYPE_STRING, "Ctrl+-") \
|
X(hotkeyZoomOut, HOTKEY_ZOOM_OUT, TYPE_STRING, "Ctrl+-") \
|
||||||
X(hotkeyPlayPause, HOTKEY_PLAY_PAUSE, TYPE_STRING, "Space") \
|
X(hotkeyPlayPause, HOTKEY_PLAY_PAUSE, TYPE_STRING, "Space") \
|
||||||
@@ -84,7 +91,7 @@
|
|||||||
X(previewIsRootTransform, PREVIEW_IS_ROOT_TRANSFORM, TYPE_BOOL, false) \
|
X(previewIsRootTransform, PREVIEW_IS_ROOT_TRANSFORM, TYPE_BOOL, false) \
|
||||||
X(previewIsTriggers, PREVIEW_IS_TRIGGERS, TYPE_BOOL, true) \
|
X(previewIsTriggers, PREVIEW_IS_TRIGGERS, TYPE_BOOL, true) \
|
||||||
X(previewIsPivots, PREVIEW_IS_PIVOTS, TYPE_BOOL, false) \
|
X(previewIsPivots, PREVIEW_IS_PIVOTS, TYPE_BOOL, false) \
|
||||||
X(previewIsTargets, PREVIEW_IS_TARGETS, TYPE_BOOL, true) \
|
X(previewIsIcons, PREVIEW_IS_ICONS, TYPE_BOOL, true) \
|
||||||
X(previewIsBorder, PREVIEW_IS_BORDER, TYPE_BOOL, false) \
|
X(previewIsBorder, PREVIEW_IS_BORDER, TYPE_BOOL, false) \
|
||||||
X(previewIsAltIcons, PREVIEW_IS_ALT_ICONS, TYPE_BOOL, false) \
|
X(previewIsAltIcons, PREVIEW_IS_ALT_ICONS, TYPE_BOOL, false) \
|
||||||
X(previewOverlayTransparency,PREVIEW_OVERLAY_TRANSPARENCY,TYPE_FLOAT, 255.0f) \
|
X(previewOverlayTransparency,PREVIEW_OVERLAY_TRANSPARENCY,TYPE_FLOAT, 255.0f) \
|
||||||
@@ -96,6 +103,8 @@
|
|||||||
X(previewAxesColor, PREVIEW_AXES_COLOR, TYPE_VEC4, {1.0,1.0,1.0,0.125}) \
|
X(previewAxesColor, PREVIEW_AXES_COLOR, TYPE_VEC4, {1.0,1.0,1.0,0.125}) \
|
||||||
X(previewBackgroundColor, PREVIEW_BACKGROUND_COLOR, TYPE_VEC4, {0.113,0.184,0.286,1.0}) \
|
X(previewBackgroundColor, PREVIEW_BACKGROUND_COLOR, TYPE_VEC4, {0.113,0.184,0.286,1.0}) \
|
||||||
\
|
\
|
||||||
|
X(propertiesIsRound, PROPERTIES_IS_ROUND, TYPE_BOOL, true) \
|
||||||
|
\
|
||||||
X(generateStartPosition, GENERATE_START_POSITION, TYPE_IVEC2, {}) \
|
X(generateStartPosition, GENERATE_START_POSITION, TYPE_IVEC2, {}) \
|
||||||
X(generateSize, GENERATE_SIZE, TYPE_IVEC2, {64,64}) \
|
X(generateSize, GENERATE_SIZE, TYPE_IVEC2, {64,64}) \
|
||||||
X(generatePivot, GENERATE_PIVOT, TYPE_IVEC2, {32,32}) \
|
X(generatePivot, GENERATE_PIVOT, TYPE_IVEC2, {32,32}) \
|
||||||
@@ -134,7 +143,7 @@
|
|||||||
X(renderType, RENDER_TYPE, TYPE_INT, RENDER_PNG) \
|
X(renderType, RENDER_TYPE, TYPE_INT, RENDER_PNG) \
|
||||||
X(renderPath, RENDER_PATH, TYPE_STRING, ".") \
|
X(renderPath, RENDER_PATH, TYPE_STRING, ".") \
|
||||||
X(renderFormat, RENDER_FORMAT, TYPE_STRING, "{}.png") \
|
X(renderFormat, RENDER_FORMAT, TYPE_STRING, "{}.png") \
|
||||||
X(ffmpegPath, FFMPEG_PATH, TYPE_STRING, "")
|
X(ffmpegPath, FFMPEG_PATH, TYPE_STRING, SETTINGS_FFMPEG_PATH_VALUE_DEFAULT)
|
||||||
|
|
||||||
#define X(name, symbol, type, ...) \
|
#define X(name, symbol, type, ...) \
|
||||||
const inline DATATYPE_TO_CTYPE(type) SETTINGS_##symbol##_DEFAULT = __VA_ARGS__;
|
const inline DATATYPE_TO_CTYPE(type) SETTINGS_##symbol##_DEFAULT = __VA_ARGS__;
|
||||||
@@ -169,6 +178,7 @@ constexpr s32 SETTINGS_COUNT = (s32)std::size(SETTINGS_ENTRIES);
|
|||||||
#define HOTKEY_LIST \
|
#define HOTKEY_LIST \
|
||||||
X(NONE, "None") \
|
X(NONE, "None") \
|
||||||
X(CENTER_VIEW, "Center View") \
|
X(CENTER_VIEW, "Center View") \
|
||||||
|
X(FIT, "Fit") \
|
||||||
X(ZOOM_IN, "Zoom In") \
|
X(ZOOM_IN, "Zoom In") \
|
||||||
X(ZOOM_OUT, "Zoom Out") \
|
X(ZOOM_OUT, "Zoom Out") \
|
||||||
X(PLAY_PAUSE, "Play/Pause") \
|
X(PLAY_PAUSE, "Play/Pause") \
|
||||||
@@ -213,6 +223,7 @@ const inline HotkeyMember SETTINGS_HOTKEY_MEMBERS[HOTKEY_COUNT] =
|
|||||||
{
|
{
|
||||||
nullptr,
|
nullptr,
|
||||||
&Settings::hotkeyCenterView,
|
&Settings::hotkeyCenterView,
|
||||||
|
&Settings::hotkeyFit,
|
||||||
&Settings::hotkeyZoomIn,
|
&Settings::hotkeyZoomIn,
|
||||||
&Settings::hotkeyZoomOut,
|
&Settings::hotkeyZoomOut,
|
||||||
&Settings::hotkeyPlayPause,
|
&Settings::hotkeyPlayPause,
|
||||||
@@ -251,66 +262,72 @@ Collapsed=0
|
|||||||
|
|
||||||
[Window][Tools]
|
[Window][Tools]
|
||||||
Pos=8,40
|
Pos=8,40
|
||||||
Size=39,612
|
Size=37,460
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x0000000B,0
|
DockId=0x0000000B,0
|
||||||
|
|
||||||
[Window][Animations]
|
[Window][Animations]
|
||||||
Pos=1288,301
|
Pos=1288,284
|
||||||
Size=304,351
|
Size=304,216
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x0000000A,0
|
DockId=0x0000000A,0
|
||||||
|
|
||||||
[Window][Events]
|
[Window][Events]
|
||||||
Pos=1005,353
|
Pos=1007,332
|
||||||
Size=281,299
|
Size=279,168
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000008,0
|
DockId=0x00000008,0
|
||||||
|
|
||||||
[Window][Spritesheets]
|
[Window][Spritesheets]
|
||||||
Pos=1288,40
|
Pos=1288,40
|
||||||
Size=304,259
|
Size=304,242
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000009,0
|
DockId=0x00000009,0
|
||||||
|
|
||||||
[Window][Animation Preview]
|
[Window][Animation Preview]
|
||||||
Pos=49,40
|
Pos=47,40
|
||||||
Size=954,612
|
Size=958,460
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x0000000C,0
|
DockId=0x0000000C,0
|
||||||
|
|
||||||
[Window][Spritesheet Editor]
|
[Window][Spritesheet Editor]
|
||||||
Pos=49,40
|
Pos=47,40
|
||||||
Size=954,612
|
Size=958,460
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x0000000C,1
|
DockId=0x0000000C,1
|
||||||
|
|
||||||
[Window][Timeline]
|
[Window][Timeline]
|
||||||
Pos=8,654
|
Pos=8,502
|
||||||
Size=1584,238
|
Size=1584,390
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000004,0
|
DockId=0x00000004,0
|
||||||
|
|
||||||
[Window][Frame Properties]
|
[Window][Frame Properties]
|
||||||
Pos=1005,40
|
Pos=1007,40
|
||||||
Size=281,311
|
Size=279,290
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000007,0
|
DockId=0x00000007,0
|
||||||
|
|
||||||
|
[Window][Onionskin]
|
||||||
|
Pos=8,502
|
||||||
|
Size=1584,390
|
||||||
|
Collapsed=0
|
||||||
|
DockId=0x00000004,1
|
||||||
|
|
||||||
[Docking][Data]
|
[Docking][Data]
|
||||||
DockSpace ID=0xFC02A410 Window=0x0E46F4F7 Pos=8,40 Size=1584,852 Split=Y
|
DockSpace ID=0xFC02A410 Window=0x0E46F4F7 Pos=8,40 Size=1584,852 Split=Y
|
||||||
DockNode ID=0x00000003 Parent=0xFC02A410 SizeRef=1902,612 Split=X
|
DockNode ID=0x00000003 Parent=0xFC02A410 SizeRef=1902,568 Split=X
|
||||||
DockNode ID=0x00000001 Parent=0x00000003 SizeRef=1278,1016 Split=X Selected=0x024430EF
|
DockNode ID=0x00000001 Parent=0x00000003 SizeRef=1595,1016 Split=X Selected=0x024430EF
|
||||||
DockNode ID=0x00000005 Parent=0x00000001 SizeRef=995,654 Split=X Selected=0x024430EF
|
DockNode ID=0x00000005 Parent=0x00000001 SizeRef=997,654 Split=X Selected=0x024430EF
|
||||||
DockNode ID=0x0000000B Parent=0x00000005 SizeRef=39,654 Selected=0x18A5FDB9
|
DockNode ID=0x0000000B Parent=0x00000005 SizeRef=37,654 Selected=0x18A5FDB9
|
||||||
DockNode ID=0x0000000C Parent=0x00000005 SizeRef=954,654 CentralNode=1 Selected=0x024430EF
|
DockNode ID=0x0000000C Parent=0x00000005 SizeRef=958,654 CentralNode=1 Selected=0x024430EF
|
||||||
DockNode ID=0x00000006 Parent=0x00000001 SizeRef=281,654 Split=Y Selected=0x754E368F
|
DockNode ID=0x00000006 Parent=0x00000001 SizeRef=279,654 Split=Y Selected=0x754E368F
|
||||||
DockNode ID=0x00000007 Parent=0x00000006 SizeRef=631,311 Selected=0x754E368F
|
DockNode ID=0x00000007 Parent=0x00000006 SizeRef=631,359 Selected=0x754E368F
|
||||||
DockNode ID=0x00000008 Parent=0x00000006 SizeRef=631,299 Selected=0x8A65D963
|
DockNode ID=0x00000008 Parent=0x00000006 SizeRef=631,207 Selected=0x8A65D963
|
||||||
DockNode ID=0x00000002 Parent=0x00000003 SizeRef=304,1016 Split=Y Selected=0x4EFD0020
|
DockNode ID=0x00000002 Parent=0x00000003 SizeRef=304,1016 Split=Y Selected=0x4EFD0020
|
||||||
DockNode ID=0x00000009 Parent=0x00000002 SizeRef=634,259 Selected=0x4EFD0020
|
DockNode ID=0x00000009 Parent=0x00000002 SizeRef=634,299 Selected=0x4EFD0020
|
||||||
DockNode ID=0x0000000A Parent=0x00000002 SizeRef=634,351 Selected=0xC1986EE2
|
DockNode ID=0x0000000A Parent=0x00000002 SizeRef=634,267 Selected=0xC1986EE2
|
||||||
DockNode ID=0x00000004 Parent=0xFC02A410 SizeRef=1902,238 Selected=0x4F89F0DC
|
DockNode ID=0x00000004 Parent=0xFC02A410 SizeRef=1902,390 Selected=0x4F89F0DC
|
||||||
)";
|
)";
|
||||||
|
|
||||||
void settings_save(Settings* self);
|
void settings_save(Settings* self);
|
||||||
|
@@ -26,13 +26,13 @@ static void _snapshot_set(Snapshots* self, Snapshot* snapshot)
|
|||||||
self->preview->time = snapshot->time;
|
self->preview->time = snapshot->time;
|
||||||
self->action = snapshot->action;
|
self->action = snapshot->action;
|
||||||
|
|
||||||
anm2_spritesheet_texture_pixels_upload(self->anm2);
|
//anm2_spritesheet_texture_pixels_upload(self->anm2);
|
||||||
}
|
}
|
||||||
|
|
||||||
Snapshot snapshot_get(Snapshots* self)
|
Snapshot snapshot_get(Snapshots* self)
|
||||||
{
|
{
|
||||||
Snapshot snapshot = {*self->anm2, *self->reference, self->preview->time, self->action};
|
Snapshot snapshot = {*self->anm2, *self->reference, self->preview->time, self->action};
|
||||||
anm2_spritesheet_texture_pixels_download(&snapshot.anm2);
|
//anm2_spritesheet_texture_pixels_download(&snapshot.anm2);
|
||||||
return snapshot;
|
return snapshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -22,18 +22,16 @@ static void _draw(State* self)
|
|||||||
SDL_GL_SwapWindow(self->window);
|
SDL_GL_SwapWindow(self->window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(State* self)
|
bool sdl_init(State* self, bool isTestMode = false)
|
||||||
{
|
{
|
||||||
settings_init(&self->settings);
|
|
||||||
|
|
||||||
if (!SDL_Init(SDL_INIT_VIDEO))
|
if (!SDL_Init(SDL_INIT_VIDEO))
|
||||||
{
|
{
|
||||||
log_error(std::format(STATE_SDL_INIT_ERROR, SDL_GetError()));
|
log_error(std::format(STATE_SDL_INIT_ERROR, SDL_GetError()));
|
||||||
quit(self);
|
quit(self);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_info(STATE_SDL_INIT_INFO);
|
if (!isTestMode) log_info(STATE_SDL_INIT_INFO);
|
||||||
|
|
||||||
// Todo, when sdl3 mixer is released officially
|
// Todo, when sdl3 mixer is released officially
|
||||||
/*
|
/*
|
||||||
@@ -61,13 +59,26 @@ void init(State* self)
|
|||||||
log_info(STATE_MIX_INIT_INFO);
|
log_info(STATE_MIX_INIT_INFO);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
self->window = SDL_CreateWindow
|
|
||||||
(
|
if (isTestMode)
|
||||||
WINDOW_TITLE,
|
{
|
||||||
self->settings.windowSize.x,
|
self->window = SDL_CreateWindow
|
||||||
self->settings.windowSize.y,
|
(
|
||||||
WINDOW_FLAGS
|
WINDOW_TITLE,
|
||||||
);
|
WINDOW_TEST_MODE_SIZE.x, WINDOW_TEST_MODE_SIZE.y,
|
||||||
|
WINDOW_TEST_MODE_FLAGS
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self->window = SDL_CreateWindow
|
||||||
|
(
|
||||||
|
WINDOW_TITLE,
|
||||||
|
self->settings.windowSize.x,
|
||||||
|
self->settings.windowSize.y,
|
||||||
|
WINDOW_FLAGS
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, STATE_GL_VERSION_MAJOR);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, STATE_GL_VERSION_MAJOR);
|
||||||
@@ -79,17 +90,17 @@ void init(State* self)
|
|||||||
{
|
{
|
||||||
log_error(std::format(STATE_GL_CONTEXT_INIT_ERROR, SDL_GetError()));
|
log_error(std::format(STATE_GL_CONTEXT_INIT_ERROR, SDL_GetError()));
|
||||||
quit(self);
|
quit(self);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress))
|
if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress))
|
||||||
{
|
{
|
||||||
log_error(std::format(STATE_GLAD_INIT_ERROR));
|
log_error(std::format(STATE_GLAD_INIT_ERROR));
|
||||||
quit(self);
|
quit(self);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_info(std::format(STATE_GL_CONTEXT_INIT_INFO, (const char*)glGetString(GL_VERSION)));
|
if (!isTestMode) log_info(std::format(STATE_GL_CONTEXT_INIT_INFO, (const char*)glGetString(GL_VERSION)));
|
||||||
|
|
||||||
window_vsync_set(self->settings.isVsync);
|
window_vsync_set(self->settings.isVsync);
|
||||||
|
|
||||||
@@ -100,6 +111,15 @@ void init(State* self)
|
|||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
glDisable(GL_LINE_SMOOTH);
|
glDisable(GL_LINE_SMOOTH);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init(State* self)
|
||||||
|
{
|
||||||
|
settings_init(&self->settings);
|
||||||
|
|
||||||
|
if (!sdl_init(self)) return;
|
||||||
|
|
||||||
if (!self->argument.empty())
|
if (!self->argument.empty())
|
||||||
{
|
{
|
||||||
anm2_deserialize(&self->anm2, self->argument);
|
anm2_deserialize(&self->anm2, self->argument);
|
||||||
|
@@ -51,6 +51,7 @@ struct State
|
|||||||
bool isRunning = true;
|
bool isRunning = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool sdl_init(State* self, bool isTestMode);
|
||||||
void init(State* state);
|
void init(State* state);
|
||||||
void loop(State* state);
|
void loop(State* state);
|
||||||
void quit(State* state);
|
void quit(State* state);
|
@@ -35,6 +35,7 @@ std::vector<u8> texture_download(const Texture* self)
|
|||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, self->id);
|
glBindTexture(GL_TEXTURE_2D, self->id);
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||||
|
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
|
||||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
|
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
|
||||||
|
|
||||||
return pixels;
|
return pixels;
|
||||||
@@ -46,12 +47,8 @@ bool texture_from_path_init(Texture* self, const std::string& path)
|
|||||||
|
|
||||||
if (!data)
|
if (!data)
|
||||||
{
|
{
|
||||||
data = stbi_load(path_canonical_resolve(path).c_str(), &self->size.x, &self->size.y, &self->channels, TEXTURE_CHANNELS);
|
log_error(std::format(TEXTURE_INIT_ERROR, path));
|
||||||
if (!data)
|
return false;
|
||||||
{
|
|
||||||
log_error(std::format(TEXTURE_INIT_ERROR, path));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self->isInvalid = false;
|
self->isInvalid = false;
|
||||||
@@ -96,13 +93,8 @@ bool texture_from_rgba_init(Texture* self, ivec2 size, s32 channels, const u8* d
|
|||||||
bool texture_from_rgba_write(const std::string& path, const u8* data, ivec2 size)
|
bool texture_from_rgba_write(const std::string& path, const u8* data, ivec2 size)
|
||||||
{
|
{
|
||||||
bool isSuccess = stbi_write_png(path.c_str(), size.x, size.y, TEXTURE_CHANNELS, data, size.x * TEXTURE_CHANNELS);
|
bool isSuccess = stbi_write_png(path.c_str(), size.x, size.y, TEXTURE_CHANNELS, data, size.x * TEXTURE_CHANNELS);
|
||||||
if (!isSuccess)
|
if (!isSuccess) log_error(std::format(TEXTURE_SAVE_ERROR, path));
|
||||||
{
|
else log_info(std::format(TEXTURE_SAVE_INFO, path));
|
||||||
isSuccess = stbi_write_png(path_canonical_resolve(path).c_str(), size.x, size.y, TEXTURE_CHANNELS, data, size.x * TEXTURE_CHANNELS);
|
|
||||||
if (!isSuccess) log_info(std::format(TEXTURE_SAVE_ERROR, path));
|
|
||||||
}
|
|
||||||
|
|
||||||
log_info(std::format(TEXTURE_SAVE_INFO, path));
|
|
||||||
|
|
||||||
return isSuccess;
|
return isSuccess;
|
||||||
}
|
}
|
||||||
|
@@ -5,6 +5,9 @@
|
|||||||
#define WINDOW_TITLE "Anm2Ed"
|
#define WINDOW_TITLE "Anm2Ed"
|
||||||
#define WINDOW_TITLE_FORMAT "Anm2Ed ({})"
|
#define WINDOW_TITLE_FORMAT "Anm2Ed ({})"
|
||||||
#define WINDOW_FLAGS SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL
|
#define WINDOW_FLAGS SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL
|
||||||
|
#define WINDOW_TEST_MODE_FLAGS WINDOW_FLAGS | SDL_WINDOW_HIDDEN
|
||||||
|
|
||||||
|
static const ivec2 WINDOW_TEST_MODE_SIZE = {1, 1};
|
||||||
|
|
||||||
void window_title_from_path_set(SDL_Window* self, const std::string& path);
|
void window_title_from_path_set(SDL_Window* self, const std::string& path);
|
||||||
bool window_color_from_position_get(SDL_Window* self, vec2 position, vec4* color);
|
bool window_color_from_position_get(SDL_Window* self, vec2 position, vec4* color);
|
||||||
|
Reference in New Issue
Block a user