diff --git a/README.md b/README.md index 5b8d0f4..d542093 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,42 @@ # Anm2ed -Reimplementation of *The Binding of Isaac: Rebirth*'s proprietary animation editor; dealing with manipulating the XML-based ".anm2" format. +![Preview](https://shweetz.net/https://shweetz.net/files/projects/anm2ed/preview.png) + +A reimplementation of *The Binding of Isaac: Rebirth*'s proprietary animation editor. Manipulates the XML-based ".anm2" format, used for in-game tweened animations. + +## Features + +- Most things present in the original IsaacAnimationEditor.exe, except some stuff like drawing (why not use an art program!) +- Smooth [Dear ImGui](https://github.com/ocornut/imgui) interface; docking, dragging and dropping, etc. +- Keybinds/keyboard control for common actions(see [src/input.h](https://github.com/ShweetsStuff/anm2ed/blob/master/src/input.h)) + +### To do +- Windows release +- Undo queue +- GIF export +- Some other things I can't think of + +### Known Issues +- Root Transform doesn't work for scale/rotation (matrix math is hard; if you can help me fix it I will give you $100.) +- Some .anm2 files used in Rebirth might not render correctly due to the ordering of layers; just drag and drop to fix the ordering and save, they will work fine afterwards. +- On startup, you will have to configure the windows yourself. +- Probably several bugs that elude me + +## Dependencies +Download these from your package manager: -# Dependencies - SDL3 - GLEW -# Build +## Build -After cloning, make sure to initialize the submodules: +After cloning and enter the repository's directory, make sure to initialize the submodules: ```git submodules update --init``` Then: ``` - mkdir build cd build diff --git a/src/imgui.cpp b/src/imgui.cpp index 4f9a094..75a9129 100644 --- a/src/imgui.cpp +++ b/src/imgui.cpp @@ -1842,6 +1842,7 @@ imgui_init Preview* preview, Settings* settings, Tool* tool, + UndoStack* undoStack, SDL_Window* window, SDL_GLContext* glContext ) @@ -1859,6 +1860,7 @@ imgui_init self->preview = preview; self->settings = settings; self->tool = tool; + self->undoStack = undoStack; self->window = window; self->glContext = glContext; @@ -1923,6 +1925,9 @@ imgui_tick(Imgui* self) _imgui_taskbar(self); _imgui_dock(self); + + if (key_press(&self->input->keyboard, INPUT_KEYS[INPUT_UNDO])) + undo_stack_pop(self->undoStack, self->anm2); } void diff --git a/src/imgui.h b/src/imgui.h index 20192f3..7256107 100644 --- a/src/imgui.h +++ b/src/imgui.h @@ -8,6 +8,7 @@ #include "input.h" #include "settings.h" #include "tool.h" +#include "undo_stack.h" #define IMGUI_IMPL_OPENGL_LOADER_CUSTOM #define IMGUI_ENABLE_DOCKING @@ -100,6 +101,7 @@ struct Imgui Preview* preview = NULL; Settings* settings = NULL; Tool* tool = NULL; + UndoStack* undoStack = NULL; SDL_Window* window = NULL; SDL_GLContext* glContext = NULL; bool isSwap = false; @@ -121,6 +123,7 @@ imgui_init Preview* preview, Settings* settings, Tool* tool, + UndoStack* undoStack, SDL_Window* window, SDL_GLContext* glContext ); diff --git a/src/input.h b/src/input.h index fa216a3..3f3f687 100644 --- a/src/input.h +++ b/src/input.h @@ -233,7 +233,7 @@ enum KeyType KEY_RGUI = 231 }; -#define INPUT_COUNT (INPUT_ZOOM_OUT + 1) +#define INPUT_COUNT (INPUT_UNDO + 1) enum InputType { INPUT_PAN, @@ -247,7 +247,8 @@ enum InputType INPUT_ROTATE_LEFT, INPUT_ROTATE_RIGHT, INPUT_ZOOM_IN, - INPUT_ZOOM_OUT + INPUT_ZOOM_OUT, + INPUT_UNDO }; static const KeyType INPUT_KEYS[INPUT_COUNT] @@ -263,7 +264,8 @@ static const KeyType INPUT_KEYS[INPUT_COUNT] KEY_Q, KEY_W, KEY_1, - KEY_2 + KEY_2, + KEY_Z }; struct Keyboard diff --git a/src/snapshots.cpp b/src/snapshots.cpp new file mode 100644 index 0000000..689f8d9 --- /dev/null +++ b/src/snapshots.cpp @@ -0,0 +1,24 @@ +#include "undo_stack.h" + +void +undo_stack_push(Snapshots* self, Anm2* anm2) +{ + if (self->top >= UNDO_STACK_MAX) + { + memmove(&self->snapshots[0], &self->snapshots[1], sizeof(Anm2) * (UNDO_STACK_MAX - 1)); + self->top = UNDO_STACK_MAX - 1; + } + + self->snapshots[self->top++] = *anm2; +} + +bool +undo_stack_pop(Snapshots* self, Anm2* anm2) +{ + if (self->top == 0) + return false; + + *anm2 = self->snapshots[--self->top]; + + return true; +} \ No newline at end of file diff --git a/src/snapshots.h b/src/snapshots.h new file mode 100644 index 0000000..1ce90ef --- /dev/null +++ b/src/snapshots.h @@ -0,0 +1,22 @@ +#pragma once + +#include "anm2.h" + +#define SNAPSHOT_STACK_MAX 100 + +struct SnapshotStack +{ + Anm2 snapshots[SNAPSHOT_STACK_MAX]; + s32 top = 0; +}; + +struct Snapshots +{ + SnapshotStack undoStack; + SnapshotStack redoStack; +} + + + +void undo_stack_push(UndoStack* self, Anm2* anm2); +bool undo_stack_pop(UndoStack* self, Anm2* anm2); \ No newline at end of file diff --git a/src/state.cpp b/src/state.cpp index 53e44d3..4674229 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -143,6 +143,7 @@ init(State* state) &state->preview, &state->settings, &state->tool, + &state->undoStack, state->window, &state->glContext ); diff --git a/src/state.h b/src/state.h index 440ab8a..65245be 100644 --- a/src/state.h +++ b/src/state.h @@ -22,6 +22,7 @@ struct State Resources resources; Settings settings; Tool tool; + UndoStack undoStack; bool isArgument = false; bool isRunning = true; char argument[PATH_MAX] = STRING_EMPTY;