Compare commits

..

3 Commits

Author SHA1 Message Date
cf9f04ecdc Float fixes, sensible settings 2025-09-14 21:27:14 -04:00
ce3f0b3415 SEMICOLON MOMENT 2025-09-14 21:03:11 -04:00
e0732ee6b9 Fixes for exit confirmation when saved 2025-09-14 21:00:54 -04:00
6 changed files with 66 additions and 24 deletions

View File

@@ -114,9 +114,21 @@ static inline std::string string_to_lowercase(std::string string) {
return string; return string;
} }
#define FLOAT_FORMAT_MAX_DECIMALS 2
#define FLOAT_FORMAT_EPSILON 1e-6f #define FLOAT_FORMAT_MAX_DECIMALS 9
static constexpr f32 FLOAT_FORMAT_POW10[] = {1.f, 10.f, 100.f}; #define FLOAT_FORMAT_EPSILON 1e-9f
static constexpr f32 FLOAT_FORMAT_POW10[] = {
1.f,
10.f,
100.f,
1000.f,
10000.f,
100000.f,
1000000.f,
10000000.f,
100000000.f,
1000000000.f
};
static inline s32 f32_decimals_needed(f32 value) static inline s32 f32_decimals_needed(f32 value)
{ {
@@ -130,8 +142,11 @@ static inline s32 f32_decimals_needed(f32 value)
for (s32 decimalCount = 1; decimalCount <= FLOAT_FORMAT_MAX_DECIMALS; ++decimalCount) for (s32 decimalCount = 1; decimalCount <= FLOAT_FORMAT_MAX_DECIMALS; ++decimalCount)
{ {
f32 scaledFraction = fractionalPart * FLOAT_FORMAT_POW10[decimalCount]; f32 scaledFraction = fractionalPart * FLOAT_FORMAT_POW10[decimalCount];
if (fabsf(scaledFraction - roundf(scaledFraction)) < FLOAT_FORMAT_EPSILON * FLOAT_FORMAT_POW10[decimalCount]) if (fabsf(scaledFraction - roundf(scaledFraction)) <
FLOAT_FORMAT_EPSILON * FLOAT_FORMAT_POW10[decimalCount])
{
return decimalCount; return decimalCount;
}
} }
return FLOAT_FORMAT_MAX_DECIMALS; return FLOAT_FORMAT_MAX_DECIMALS;
} }
@@ -140,7 +155,9 @@ static inline const char* f32_format_get(f32 value)
{ {
static std::string formatString; static std::string formatString;
const s32 decimalCount = f32_decimals_needed(value); const s32 decimalCount = f32_decimals_needed(value);
formatString = (decimalCount == 0) ? "%.0f" : ("%." + std::to_string(decimalCount) + "f"); formatString = (decimalCount == 0)
? "%.0f"
: ("%." + std::to_string(decimalCount) + "f");
return formatString.c_str(); return formatString.c_str();
} }
@@ -150,7 +167,9 @@ static inline const char* vec2_format_get(const vec2& value)
const s32 decimalCountX = f32_decimals_needed(value.x); const s32 decimalCountX = f32_decimals_needed(value.x);
const s32 decimalCountY = f32_decimals_needed(value.y); const s32 decimalCountY = f32_decimals_needed(value.y);
const s32 decimalCount = (decimalCountX > decimalCountY) ? decimalCountX : decimalCountY; const s32 decimalCount = (decimalCountX > decimalCountY) ? decimalCountX : decimalCountY;
formatString = (decimalCount == 0) ? "%.0f" : ("%." + std::to_string(decimalCount) + "f"); formatString = (decimalCount == 0)
? "%.0f"
: ("%." + std::to_string(decimalCount) + "f");
return formatString.c_str(); return formatString.c_str();
} }

View File

@@ -137,23 +137,31 @@ struct Anm2Spritesheet
std::string path{}; std::string path{};
Texture texture; Texture texture;
std::vector<u8> pixels; std::vector<u8> pixels;
auto operator<=>(const Anm2Spritesheet&) const = default;
}; };
struct Anm2Layer struct Anm2Layer
{ {
std::string name = "New Layer"; std::string name = "New Layer";
s32 spritesheetID{}; s32 spritesheetID{};
auto operator<=>(const Anm2Layer&) const = default;
}; };
struct Anm2Null struct Anm2Null
{ {
std::string name = "New Null"; std::string name = "New Null";
bool isShowRect = false; bool isShowRect = false;
auto operator<=>(const Anm2Null&) const = default;
}; };
struct Anm2Event struct Anm2Event
{ {
std::string name = "New Event"; std::string name = "New Event";
auto operator<=>(const Anm2Event&) const = default;
}; };
struct Anm2Frame struct Anm2Frame
@@ -171,27 +179,16 @@ struct Anm2Frame
vec2 scale = {100, 100}; vec2 scale = {100, 100};
vec3 offsetRGB = COLOR_OFFSET_NONE; vec3 offsetRGB = COLOR_OFFSET_NONE;
vec4 tintRGBA = COLOR_OPAQUE; vec4 tintRGBA = COLOR_OPAQUE;
};
struct Anm2FrameChange auto operator<=>(const Anm2Frame&) const = default;
{
std::optional<bool> isVisible;
std::optional<bool> isInterpolated;
std::optional<f32> rotation;
std::optional<s32> delay;
std::optional<vec2> crop;
std::optional<vec2> pivot;
std::optional<vec2> position;
std::optional<vec2> size;
std::optional<vec2> scale;
std::optional<vec3> offsetRGB;
std::optional<vec4> tintRGBA;
}; };
struct Anm2Item struct Anm2Item
{ {
bool isVisible = true; bool isVisible = true;
std::vector<Anm2Frame> frames; std::vector<Anm2Frame> frames;
auto operator<=>(const Anm2Item&) const = default;
}; };
struct Anm2Animation struct Anm2Animation
@@ -204,6 +201,8 @@ struct Anm2Animation
std::vector<s32> layerOrder; std::vector<s32> layerOrder;
std::map<s32, Anm2Item> nullAnimations; std::map<s32, Anm2Item> nullAnimations;
Anm2Item triggers; Anm2Item triggers;
auto operator<=>(const Anm2Animation&) const = default;
}; };
struct Anm2 struct Anm2
@@ -219,6 +218,8 @@ struct Anm2
s32 defaultAnimationID = ID_NONE; s32 defaultAnimationID = ID_NONE;
s32 fps = ANM2_FPS_DEFAULT; s32 fps = ANM2_FPS_DEFAULT;
s32 version{}; s32 version{};
auto operator<=>(const Anm2&) const = default;
}; };
struct Anm2Reference struct Anm2Reference
@@ -231,6 +232,21 @@ struct Anm2Reference
auto operator<=>(const Anm2Reference&) const = default; auto operator<=>(const Anm2Reference&) const = default;
}; };
struct Anm2FrameChange
{
std::optional<bool> isVisible;
std::optional<bool> isInterpolated;
std::optional<f32> rotation;
std::optional<s32> delay;
std::optional<vec2> crop;
std::optional<vec2> pivot;
std::optional<vec2> position;
std::optional<vec2> size;
std::optional<vec2> scale;
std::optional<vec3> offsetRGB;
std::optional<vec4> tintRGBA;
};
enum Anm2MergeType enum Anm2MergeType
{ {
ANM2_MERGE_APPEND_FRAMES, ANM2_MERGE_APPEND_FRAMES,

View File

@@ -3012,6 +3012,8 @@ void imgui_init
self->window = window; self->window = window;
self->glContext = glContext; self->glContext = glContext;
self->saveAnm2 = *anm2;
ImGui::CreateContext(); ImGui::CreateContext();
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
@@ -3032,6 +3034,7 @@ void imgui_init
if (!SETTINGS_HOTKEY_MEMBERS[i]) continue; if (!SETTINGS_HOTKEY_MEMBERS[i]) continue;
imgui_hotkey_chord_registry()[i] = imgui_chord_from_string_get(*&(self->settings->*SETTINGS_HOTKEY_MEMBERS[i])); imgui_hotkey_chord_registry()[i] = imgui_chord_from_string_get(*&(self->settings->*SETTINGS_HOTKEY_MEMBERS[i]));
} }
} }
void imgui_update(Imgui* self) void imgui_update(Imgui* self)

View File

@@ -209,6 +209,7 @@ struct Imgui
ImguiPopupType pendingPopupType = IMGUI_POPUP_NONE; ImguiPopupType pendingPopupType = IMGUI_POPUP_NONE;
ImVec2 pendingPopupPosition{}; ImVec2 pendingPopupPosition{};
std::vector<ImguiLogItem> log; std::vector<ImguiLogItem> log;
Anm2 saveAnm2;
SDL_SystemCursor cursor; SDL_SystemCursor cursor;
SDL_SystemCursor pendingCursor; SDL_SystemCursor pendingCursor;
bool isCursorSet = false; bool isCursorSet = false;
@@ -217,7 +218,6 @@ struct Imgui
bool isTryQuit = false; bool isTryQuit = false;
}; };
static inline void imgui_snapshot(Imgui* self, const std::string& action = SNAPSHOT_ACTION) static inline void imgui_snapshot(Imgui* self, const std::string& action = SNAPSHOT_ACTION)
{ {
self->snapshots->action = action; self->snapshots->action = action;
@@ -252,6 +252,8 @@ static inline void imgui_file_save(Imgui* self)
anm2_serialize(self->anm2, self->anm2->path); anm2_serialize(self->anm2, self->anm2->path);
imgui_log_push(self, std::format(IMGUI_LOG_FILE_SAVE_FORMAT, self->anm2->path)); imgui_log_push(self, std::format(IMGUI_LOG_FILE_SAVE_FORMAT, self->anm2->path));
} }
self->saveAnm2 = *self->anm2;
} }
static inline void imgui_file_new(Imgui* self) static inline void imgui_file_new(Imgui* self)
@@ -269,7 +271,7 @@ static inline void imgui_file_save_as(Imgui* self)
static inline void imgui_quit(Imgui* self) static inline void imgui_quit(Imgui* self)
{ {
if (!self->snapshots->undoStack.is_empty()) if (self->saveAnm2 != *self->anm2)
self->isTryQuit = true; self->isTryQuit = true;
else else
self->isQuit = true; self->isQuit = true;

View File

@@ -88,7 +88,7 @@
\ \
X(previewIsAxes, PREVIEW_IS_AXES, TYPE_BOOL, true) \ X(previewIsAxes, PREVIEW_IS_AXES, TYPE_BOOL, true) \
X(previewIsGrid, PREVIEW_IS_GRID, TYPE_BOOL, true) \ X(previewIsGrid, PREVIEW_IS_GRID, TYPE_BOOL, true) \
X(previewIsRootTransform, PREVIEW_IS_ROOT_TRANSFORM, TYPE_BOOL, false) \ X(previewIsRootTransform, PREVIEW_IS_ROOT_TRANSFORM, TYPE_BOOL, true) \
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(previewIsIcons, PREVIEW_IS_ICONS, TYPE_BOOL, true) \ X(previewIsIcons, PREVIEW_IS_ICONS, TYPE_BOOL, true) \
@@ -103,7 +103,7 @@
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(propertiesIsRound, PROPERTIES_IS_ROUND, TYPE_BOOL, false) \
\ \
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}) \

View File

@@ -13,6 +13,8 @@ struct Texture
GLuint id = GL_ID_NONE; GLuint id = GL_ID_NONE;
ivec2 size{}; ivec2 size{};
bool isInvalid = true; bool isInvalid = true;
auto operator<=>(const Texture&) const = default;
}; };
bool texture_from_encoded_data_init(Texture* self, ivec2 size, const u8* data, u32 length); bool texture_from_encoded_data_init(Texture* self, ivec2 size, const u8* data, u32 length);