From bedd6906eabdd513042d6a178d4dc56a3a41d1d3 Mon Sep 17 00:00:00 2001 From: Fox Caminiti Date: Fri, 16 Dec 2022 20:16:43 -0500 Subject: v3, file/build organization --- src/include/debug.h | 99 +++++ src/include/defines.h | 52 +++ src/include/ffmpeg_backend.h | 37 ++ src/include/functions.h | 90 +++++ src/include/gl_calls.h | 24 ++ src/include/imgui_internal_widgets.h | 15 + src/include/imgui_ops.h | 106 +++++ src/include/keybinds.h | 205 ++++++++++ src/include/layer.h | 50 +++ src/include/main.h | 686 +++++++++++++++++++++++++++++++ src/include/memory.h | 71 ++++ src/include/my_math.h | 762 +++++++++++++++++++++++++++++++++++ src/include/sharebuffer.h | 17 + src/include/stable_diffusion.h | 33 ++ src/include/structs.h | 5 + src/include/undo.h | 2 + 16 files changed, 2254 insertions(+) create mode 100644 src/include/debug.h create mode 100644 src/include/defines.h create mode 100644 src/include/ffmpeg_backend.h create mode 100644 src/include/functions.h create mode 100644 src/include/gl_calls.h create mode 100644 src/include/imgui_internal_widgets.h create mode 100644 src/include/imgui_ops.h create mode 100644 src/include/keybinds.h create mode 100644 src/include/layer.h create mode 100644 src/include/main.h create mode 100644 src/include/memory.h create mode 100644 src/include/my_math.h create mode 100644 src/include/sharebuffer.h create mode 100644 src/include/stable_diffusion.h create mode 100644 src/include/structs.h create mode 100644 src/include/undo.h (limited to 'src/include') diff --git a/src/include/debug.h b/src/include/debug.h new file mode 100644 index 0000000..6321679 --- /dev/null +++ b/src/include/debug.h @@ -0,0 +1,99 @@ +#if DEBUG + +static int32 *debugnull = NULL; +#define Assert(Expression) if(!(Expression)) {*debugnull = 21;} + +enum valtype { + d_float, + d_uint, + d_int +}; + +union debugval { + real32 f; + uint32 u; + int32 i; +}; + +// things that get cleared every frame with the UI +struct debug_temp +{ + valtype DebugPropertyType[16]; + debugval Val[16]; + char *String[16]; + uint32 WatchedProperties; +}; + +struct project_debug +{ + debug_temp Temp; + bool32 ToggleWindow = 1; + bool32 ReloadUI = true; + bool32 NoThreading = 0; + bool32 DisableAlpha = 0; + uint64 PixelCountTransparent; + uint64 PixelCountRendered; + uint64 PixelCountChecked; + // NOTE(fox): Pixel count isn't thread safe; don't use with multithreading! + uint64 LayerCycleCount[64]; + uint32 UndoState = 0; + uint64 ScratchSize[6]; + uint32 ScratchState = 0; +}; + +static project_debug Debug; + +static void +DebugWatchVar(char *Name, void *Address, valtype Type) { + uint32 i = Debug.Temp.WatchedProperties; + Debug.Temp.String[i] = Name; + if (Type == d_float) + Debug.Temp.Val[i].f = *(real32 *)Address; + if (Type == d_uint) + Debug.Temp.Val[i].u = *(uint32 *)Address; + if (Type == d_int) + Debug.Temp.Val[i].i = *(int32 *)Address; + Debug.Temp.DebugPropertyType[i] = Type; + Debug.Temp.WatchedProperties++; +} + +#else + +#define Assert(Expression) + +enum valtype { +}; + +union debugval { +}; + +struct debug_temp +{ +}; + +struct project_debug +{ +}; + +static void +DebugWatchVar(char *Name, void *Address, valtype Type) { +} + +static void +DebugPrintMemoryUsage(memory Memory) { +} +#endif + +#ifdef PERF + +struct perf_stats +{ + uint64 PixelCountTransparent; + uint64 PixelCountRendered; + uint64 PixelCountChecked; +}; + +static uint64 Test; + +#endif + diff --git a/src/include/defines.h b/src/include/defines.h new file mode 100644 index 0000000..8216f1c --- /dev/null +++ b/src/include/defines.h @@ -0,0 +1,52 @@ +typedef int8_t int8; +typedef int16_t int16; +typedef int32_t int32; + +typedef int64_t int64; +typedef int32 bool32; + +typedef uint8_t uint8; +typedef uint16_t uint16; +typedef uint32_t uint32; +typedef uint64_t uint64; + +typedef float real32; +typedef double real64; + +typedef uint64 ptrsize; // is there a compiler variable for 32 vs 64 bit like this? + +#define NORMALIZED_COL_MIN V4(0.0f, 0.0f, 0.0f, 0.0f) +#define NORMALIZED_COL_MAX V4(1.0f, 1.0f, 1.0f, 1.0f) +#define NORMALIZED_REAL_MIN { 0.0f } +#define NORMALIZED_REAL_MAX { 1.0f } + +#define TESS_TOL 1.5f // Level of tesselation for bezier calculations; ImGui's default value + +// All of these MIN/MAX values are arbitrarily chosen; they can probably be +// increased if the user requires it. + +#define PROPERTY_REAL_MAX 1000000 +#define PROPERTY_REAL_MIN -1000000 + +#define MAX_LAYERS 2048 +#define MAX_EFFECTS 32 +#define MAX_SOURCES 1024 +#define MAX_COMPS 1024 +#define MAX_PRECOMP_RECURSIONS 4 +#define MAX_MASKS 8 +#define MAX_PROPERTIES_PER_EFFECT 80 // Kinda high since we want to support 8 xy points of Curves data across 5 channels. +#define MAX_KEYFRAME_BLOCKS 64 +#define MAX_KEYFRAMES_PER_BLOCK 32 // max keyframes on a single channel is 2048 + +#define MAX_SELECTED_PROPERTIES 16 + +#define AmountOf(Array) sizeof((Array)) / sizeof((Array)[1]) + +#if ARM +#define GetCPUTime() 0 +#else +#define GetCPUTime() __rdtsc() +#endif + +static real32 Tau = 0.9; // tension + diff --git a/src/include/ffmpeg_backend.h b/src/include/ffmpeg_backend.h new file mode 100644 index 0000000..717a33d --- /dev/null +++ b/src/include/ffmpeg_backend.h @@ -0,0 +1,37 @@ +// NOTE(fox): Even though each layer has its own completely isolated AV +// instance, it appears two layers with the same file still share something. +// When the layers aren't at the same position in time, the playhead of one +// layer gets misaligned every few frames and causes a manual seek back to the +// position. Different files don't exhibit this behavior. + +struct av_stream_info { + uint32 Index; + AVCodecParameters *CodecParameters; // Used to supply info about the decoder. + const AVCodec* Codec; + AVStream *Stream; // Which stream, or channel, the video is in. Holds FPS info and is used to verify that the decoded packet belongs to this stream. + AVCodecContext *CodecContext; +}; + + +struct av_info { + uint8 Occupied; + + uint16 Block_Source_Index; + + int LastFrameRendered; // Convenient to know this to only seek when we actually need to. + uint64 PreviousPTS; // PTS value of the previous frame, used to check timings in debug. + + AVFormatContext *FileFormatContext; // Umbrella for everything else, seems to contain the playhead state + + av_stream_info Video; + av_stream_info Audio; + + AVPacket *Packet; + AVFrame *Frame; + + uint32 FrameCount; + uint64 PTSDuration; // likely not always 100% accurate + + SwsContext *RGBContext; +}; + diff --git a/src/include/functions.h b/src/include/functions.h new file mode 100644 index 0000000..23d741e --- /dev/null +++ b/src/include/functions.h @@ -0,0 +1,90 @@ + +// Memory + +static void Memory_Copy(uint8 *Address_Write, uint8 *Address_Read, uint64 Size); +static void Arbitrary_Zero(uint8 *Address_Write, uint64 Size); +static void Arbitrary_SwapData(memory *Memory, uint8 *Address_0, uint8 *Address_1, uint64 Size); +static void Arbitrary_ShiftData(uint8 *Address_Start, uint8 *Address_End, uint64 ShiftAmount, int32 Direction); + + +// Rudimentary guess-until-correct solver for bezier curves, used to evaluate +// the keyframe graph. Similar to the Catmull-Rom solver in CurvesSolver(). + +static real32 Bezier_SolveYForX(v2 Point_P0, v2 Point_P1, v2 Point_P2, v2 Point_P3, real32 TargetX); +static bezier_point * Bezier_LookupAddress(memory *Memory, property_channel *Property, uint16 Index, bool32 AssertExists = 1); +static void Bezier_Interact_Evaluate(project_state *State, bezier_point *PointAddress, v2 *Pos, real32 GraphZoomHeight = 1, real32 Y_Increment = 1); +// NOTE(fox): GraphZoomHeight and Y_Increment don't have to be specified if the Y value isn't needed, i.e. in Property_SortAll(). +static void Bezier_Add(memory *Memory, memory_table_list TableName, property_channel *Property, bezier_point PointData, uint16 *ArrayLocation); + + +static void ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io, sorted_file Sorted); +static void ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, sorted_property_array *SortedPropertyStart, uint16 *SortedKeyframeArray); +static void ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io, GLuint textureID, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, uint16 *SortedKeyframeArray); +static void ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, sorted_property_array *SortedPropertyStart, uint16 *SortedKeyframeArray); + +static void ImGui_File(project_data *File, project_state *State, memory *Memory, ImGuiIO io, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray); +static void ImGui_EffectsPanel(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io); +static void ImGui_ColorPanel(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io); + +static void ImGui_Menu(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io); +static void ImGui_Popups(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io); +static void ImGui_KeybindUI(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io); + +#if DEBUG +static void ImGui_DebugMemoryViewer(memory *Memory, project_state *State); +static void ImGui_DebugRenderQueue(project_state *State); +static void ImGui_DebugUndoTree(memory *Memory, project_state *State); +#endif +#if SD +static void ImGui_SD_Thumbnail(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, uint16 *SourceArray, uint16 SourceCount); +static void ImGui_SD_Prompt(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray); +#endif + +// Widgets not involving drawing UI. + +static v2 ImGui_ScreenPointToCompUV(ImVec2 ViewportMin, ImVec2 CompPos, ImVec2 CompZoom, ImVec2 MousePos); +static void ImGui_WarpMouse(project_state *State, ImVec2 MousePos, ImVec2 Min, ImVec2 Max, int Direction = 3); +static void ImGui_WarpMouseFinish(project_state *State, ImVec2 MousePos); +static ImVec2 ImGui_Brush_CalcMousePos(project_state *State, ImGuiIO &io, ImVec2 MouseDelta, int32 i, real32 DeltaDistance, real32 DeltaSlope); +static bool32 ImGui_TestBoxSelection_Point(ImVec2 Pos, ImGuiIO &io, bool32 *Test); + + +static void +Render_Main(project_data *File, project_state *State, memory *Memory, sorted_file Sorted, ui *UI, SDL_Window *window, GLuint textureID, + void *Data, void *OutputBuffer, render_type RenderType, rectangle RenderRegion); + +static void Effect_Curves_Init(block_effect *Effect, property_channel *Property); + +void AV_IsFileSupported(char *filename, bool32 *IsVideo, bool32 *HasAudio); + +static v2 T_CompUVToLayerUV(layer_transforms T, uint32 FileWidth, uint32 FileHeight, uint32 SourceWidth, uint32 SourceHeight, v2 CompUV); +static header_effect* Effect_EntryFromID(project_state *State, char *ID); + +void Effect_Curves_Sort(memory *Memory, block_effect *Effect, uint16 *SortedPointStart, uint16 Which); +inline v2 Effect_V2(memory *Memory, block_effect *Effect, int Offset); + +static void Interact_Transform_Begin(project_data *File, memory *Memory, project_state *State, ImVec2 OGPos, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray); + +static v2 Transform_ScreenSpaceToLocal(layer_transforms T, uint32 FileWidth, uint32 FileHeight, uint32 SourceWidth, uint32 SourceHeight, ImVec2 CompPos, ImVec2 CompZoom, ImVec2 ViewportMin, ImVec2 Point); +static ImVec2 Layer_LocalToScreenSpace(project_state *State, memory *Memory, block_layer *Layer, ui *UI, uint32 PrincipalCompIndex, v2 Point); + +static v2 TransformPoint(layer_transforms T, real32 Width, real32 Height, v2 Point); + +static void Layer_GetDimensions(memory *Memory, block_layer *Layer, int *Width, int *Height); + +static void * Memory_PushScratch(memory *Memory, uint64 Size); + +static void Memory_PopScratch(memory *Memory, uint64 Size); + +void Bitmap_SwapData(uint8 *Address_0, uint8 *Address_1, uint64 Size, uint16 BytesPerPixel); +void GL_DeleteHWBuffer(gl_effect_layer *Test); + +void GL_UpdateTexture(gl_effect_layer *Test, void *Data, uint16 Width, uint16 Height, uint16 BytesPerPixel, bool32 Multisample); + +static void Transform_ApplyInteractive(interact_transform Interact, real32 *OutputX, real32 *OutputY, real32 *OutputRotation, real32 *OutputScale); + +static layer_transforms Layer_GetTransforms(block_layer *Layer); +void GL_GenAndBindTexture(GLuint *GLTexture, int Width, int Height, int BytesPerPixel, void *BufferAddress); + +static real32 Bezier_SolveYForX(v2 Point_P0, v2 Point_P1, v2 Point_P2, v2 Point_P3, real32 X); + diff --git a/src/include/gl_calls.h b/src/include/gl_calls.h new file mode 100644 index 0000000..fa0a00c --- /dev/null +++ b/src/include/gl_calls.h @@ -0,0 +1,24 @@ +struct default_gl_vertex_object { + uint32 VertexArrayObject; + uint32 VertexBufferObject; + uint32 ElementBufferObject; +}; + +struct gl_vertex_shader { + uint32 VertexArrayObject; + uint32 VertexBufferObject; +}; + +static default_gl_vertex_object DefaultVerts; +static gl_vertex_shader GL_DefaultVertexObjects; +static uint32 DefaultVertexShader; +static uint32 DefaultShaderProgram; +static uint32 MaskShaderProgram; + +float GL_DefaultVertices[] = { + 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, + 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, + -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, + -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, +}; + diff --git a/src/include/imgui_internal_widgets.h b/src/include/imgui_internal_widgets.h new file mode 100644 index 0000000..52fdc74 --- /dev/null +++ b/src/include/imgui_internal_widgets.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#include + +// NOTE(fox): Appending to the standard ImGui namespace so I don't have to convert all the functions to ImGui::Function() +namespace ImGui { + IMGUI_API bool SliderLevels(const char* label, const char* label2, const char* label3, void* p_data, void* p_min, void* p_max); + IMGUI_API bool TestLine(ImVec2 P1, ImVec2 P2); + IMGUI_API bool BezierInteractive(ImVec2 p0, ImVec2 p1, ImVec2 p2, ImVec2 p3); + IMGUI_API bool LineInteractive(ImVec2 p0, ImVec2 p1); + IMGUI_API ImVec2 RatioToPoint(ImVec2 a, ImVec2 b, float ratio); +} + diff --git a/src/include/imgui_ops.h b/src/include/imgui_ops.h new file mode 100644 index 0000000..6089f94 --- /dev/null +++ b/src/include/imgui_ops.h @@ -0,0 +1,106 @@ + + +ImVec2 operator+(ImVec2 A, ImVec2 B) +{ + ImVec2 Result; + + Result.x = A.x + B.x; + Result.y = A.y + B.y; + + return Result; +} + +ImVec2 operator+(ImVec2 A, int B) +{ + ImVec2 Result; + + Result.x = A.x + B; + Result.y = A.y + B; + + return Result; +} + +ImVec2 operator-(ImVec2 A, int B) +{ + ImVec2 Result; + + Result.x = A.x - B; + Result.y = A.y - B; + + return Result; +} + +ImVec2 operator-(ImVec2 A, ImVec2 B) +{ + ImVec2 Result; + + Result.x = A.x - B.x; + Result.y = A.y - B.y; + + return Result; +} + +ImVec2 operator*(ImVec2 A, real32 B) +{ + ImVec2 Result; + + Result.x = A.x * B; + Result.y = A.y * B; + + return Result; +} + +ImVec2 operator*(ImVec2 A, ImVec2 B) +{ + ImVec2 Result; + + Result.x = A.x * B.x; + Result.y = A.y * B.y; + + return Result; +} + +ImVec2 operator/(ImVec2 A, ImVec2 B) +{ + ImVec2 Result; + + Result.x = A.x / B.x; + Result.y = A.y / B.y; + + return Result; +} + +ImVec2 operator/(ImVec2 A, real32 B) +{ + ImVec2 Result; + + Result.x = A.x / B; + Result.y = A.y / B; + + return Result; +} + +ImVec2 operator/(real32 A, ImVec2 B) +{ + ImVec2 Result; + + Result.x = A / B.x; + Result.y = A / B.y; + + return Result; +} + +inline bool32 +IsRectTouching(ImVec2 Min1, ImVec2 Max1, ImVec2 Min2, ImVec2 Max2) +{ + bool32 Result = 0; + if ((Max1.x > Min2.x && Min1.x < Min2.x) && + (Max1.y > Min2.y && Min1.y < Min2.y)) + Result = 1; + // if ( + // Result = 1; + // if (Min1.x > Min2.x) + + return(Result); +} + diff --git a/src/include/keybinds.h b/src/include/keybinds.h new file mode 100644 index 0000000..3fe5f64 --- /dev/null +++ b/src/include/keybinds.h @@ -0,0 +1,205 @@ +enum key_mode { + key_mode_all, + key_mode_viewport, + key_mode_timeline, + key_mode_graph, + key_mode_brush, + key_mode_count, +}; + +enum key_mods { + Mod_None, + Mod_Ctrl, + Mod_Alt, + Mod_Shift, + Mod_CtrlShift +}; + +struct shortcut_entry { + ImGuiKey_ Key; + key_mods Mods; + key_mode Mode; + char *Name; +}; + +static shortcut_entry ShortcutArray[] { + { ImGuiKey_None, Mod_None, key_mode_all, "Many actions/modes are escapable with the Esc key." }, + { ImGuiKey_None, Mod_None, key_mode_all, "Undo isn't fully implemented yet; beware crashes." }, + { ImGuiKey_Q, Mod_None, key_mode_all, "Quit (instantly!)" }, + { ImGuiKey_W, Mod_None, key_mode_all, "Step back one frame" }, + { ImGuiKey_E, Mod_None, key_mode_all, "Step forward one frame" }, + { ImGuiKey_V, Mod_None, key_mode_all, "Move tool" }, + { ImGuiKey_B, Mod_None, key_mode_all, "Brush tool" }, + { ImGuiKey_Space, Mod_None, key_mode_all, "Play scene" }, + { ImGuiKey_Delete, Mod_None, key_mode_all, "Delete selection (WIP)" }, + { ImGuiKey_S, Mod_Ctrl, key_mode_all, "Save" }, + { ImGuiKey_S, Mod_CtrlShift, key_mode_all, "Save as" }, + { ImGuiKey_C, Mod_Ctrl, key_mode_all, "Copy" }, + { ImGuiKey_P, Mod_Ctrl, key_mode_all, "Paste" }, + { ImGuiKey_Z, Mod_Ctrl, key_mode_all, "Undo" }, + { ImGuiKey_Z, Mod_Ctrl, key_mode_all, "Redo" }, + { ImGuiKey_Space, Mod_Shift, key_mode_all, "Focus effects search" }, + { ImGuiKey_Slash, Mod_Shift, key_mode_all, "Open help" }, + + { ImGuiKey_None, Mod_None, key_mode_viewport, "Hold right click to pan." }, + { ImGuiKey_None, Mod_None, key_mode_viewport, "Hold Z and drag left click to zoom." }, + { ImGuiKey_None, Mod_None, key_mode_viewport, "Press Enter or ctrl+click to commit a transform." }, + { ImGuiKey_T, Mod_None, key_mode_viewport, "Transform selected layers" }, + + { ImGuiKey_Tab, Mod_None, key_mode_timeline, "Switch between timeline and graph" }, + { ImGuiKey_2, Mod_None, key_mode_timeline, "Toggle precomp view" }, + { ImGuiKey_G, Mod_None, key_mode_timeline, "Toggle position keyframes" }, + { ImGuiKey_A, Mod_None, key_mode_timeline, "Toggle anchor point keyframes" }, + { ImGuiKey_R, Mod_None, key_mode_timeline, "Toggle roation keyframes" }, + { ImGuiKey_S, Mod_None, key_mode_timeline, "Toggle scale keyframes" }, + { ImGuiKey_T, Mod_None, key_mode_timeline, "Toggle time remapping keyframes" }, + { ImGuiKey_T, Mod_Shift, key_mode_timeline, "Toggle opacity keyframes" }, + { ImGuiKey_U, Mod_None, key_mode_timeline, "Toggle all active channels" }, + { ImGuiKey_N, Mod_None, key_mode_timeline, "Mark frame start" }, + { ImGuiKey_N, Mod_Shift, key_mode_timeline, "Mark frame end" }, + + { ImGuiKey_G, Mod_None, key_mode_graph, "Enter keyframe moving mode" }, + { ImGuiKey_X, Mod_None, key_mode_graph, "Constrain to X axis" }, + { ImGuiKey_Y, Mod_None, key_mode_graph, "Constrain to Y axis" }, + + { ImGuiKey_None, Mod_None, key_mode_brush, "Hold alt and drag to adjust size/hardness." }, + { ImGuiKey_X, Mod_None, key_mode_brush, "Swap FG and BG colors" }, +}; + + +struct key_entry { + ImGuiKey_ KeyIndex; + char *Name; + char *ShiftName; + uint32 Sector; + ImVec2 Offset; + real32 WidthRatio; +}; + +// dumb typing exercise +static key_entry KeyEntries[] { + { ImGuiKey_Tab, "Tab", "\0", 0, ImVec2(0, 1), 1.5f }, + { ImGuiKey_LeftArrow, "<-", "\0", 2, ImVec2(0, 4), 1.0f }, + { ImGuiKey_RightArrow, "->", "", 2, ImVec2(2, 4), 1.0f }, + { ImGuiKey_UpArrow, "/\\", "", 2, ImVec2(1, 3), 1.0f }, + { ImGuiKey_DownArrow, "\\/", "", 2, ImVec2(1, 4), 1.0f }, + { ImGuiKey_PageUp, "Up", "", 2, ImVec2(2, 0), 1.0f }, + { ImGuiKey_PageDown, "Dn", "", 2, ImVec2(2, 1), 1.0f }, + { ImGuiKey_Home, "Home", "", 2, ImVec2(1, 0), 1.0f }, + { ImGuiKey_End, "End", "", 2, ImVec2(1, 1), 1.0f }, + { ImGuiKey_Insert, "Insert", "", 2, ImVec2(0, 0), 1.0f }, + { ImGuiKey_Delete, "Delete", "", 2, ImVec2(0, 1), 1.0f }, + { ImGuiKey_Backspace, "Backspace", "", 0, ImVec2(13, 0), 2.0f }, + { ImGuiKey_Space, "Space", "", 0, ImVec2(3.75, 4), 6.5f }, + { ImGuiKey_Enter, "Enter", "", 0, ImVec2(12, 2), 2.25f}, + { ImGuiKey_Escape, "Esc", "", 1, ImVec2(0, 0), 1.0f }, + { ImGuiKey_LeftCtrl, "Ctrl", "", 0, ImVec2(0, 4), 1.25f }, + { ImGuiKey_LeftShift, "Shift", "", 0, ImVec2(0, 3), 2.5f }, + { ImGuiKey_LeftAlt, "Alt", "", 0, ImVec2(1.25, 4), 1.25 }, + { ImGuiKey_LeftSuper, "Sp", "", 0, ImVec2(2.5, 4), 1.25f }, + { ImGuiKey_RightCtrl, "Ctrl", "", 0, ImVec2(13.75, 4), 1.25f }, + { ImGuiKey_RightShift, "Shift", "", 0, ImVec2(11, 3), 2.5f }, + { ImGuiKey_RightAlt, "Alt", "", 0, ImVec2(11.25, 4), 1.25 }, + { ImGuiKey_RightSuper, "Sp", "", 0, ImVec2(10.25, 4), 1.0f }, + { ImGuiKey_Menu, "Menu", "", 0, ImVec2(12.5, 4), 1.25 }, + { ImGuiKey_0, "0", ")", 0, ImVec2(10, 0), 1.0f }, + { ImGuiKey_1, "1", "!", 0, ImVec2(1, 0), 1.0f }, + { ImGuiKey_2, "2", "@", 0, ImVec2(2, 0), 1.0f }, + { ImGuiKey_3, "3", "$", 0, ImVec2(3, 0), 1.0f }, + { ImGuiKey_4, "4", "%", 0, ImVec2(4, 0), 1.0f }, + { ImGuiKey_5, "5", "%", 0, ImVec2(5, 0), 1.0f }, + { ImGuiKey_6, "6", "^", 0, ImVec2(6, 0), 1.0f }, + { ImGuiKey_7, "7", "&", 0, ImVec2(7, 0), 1.0f }, + { ImGuiKey_8, "8", "*", 0, ImVec2(8, 0), 1.0f }, + { ImGuiKey_9, "9", "(", 0, ImVec2(9, 0), 1.0f }, + { ImGuiKey_A, "a", "A", 0, ImVec2(1, 2), 1.0f }, + { ImGuiKey_B, "b", "B", 0, ImVec2(5, 3), 1.0f }, + { ImGuiKey_C, "c", "C", 0, ImVec2(3, 3), 1.0f }, + { ImGuiKey_D, "d", "D", 0, ImVec2(3, 2), 1.0f }, + { ImGuiKey_E, "e", "E", 0, ImVec2(3, 1), 1.0f }, + { ImGuiKey_F, "f", "F", 0, ImVec2(4, 2), 1.0f }, + { ImGuiKey_G, "g", "G", 0, ImVec2(5, 2), 1.0f }, + { ImGuiKey_H, "h", "H", 0, ImVec2(6, 2), 1.0f }, + { ImGuiKey_I, "i", "I", 0, ImVec2(8, 1), 1.0f }, + { ImGuiKey_J, "j", "J", 0, ImVec2(7, 2), 1.0f }, + { ImGuiKey_K, "k", "K", 0, ImVec2(8, 2), 1.0f }, + { ImGuiKey_L, "l", "L", 0, ImVec2(9, 2), 1.0f }, + { ImGuiKey_M, "m", "M", 0, ImVec2(7, 3), 1.0f }, + { ImGuiKey_N, "n", "N", 0, ImVec2(6, 3), 1.0f }, + { ImGuiKey_O, "o", "O", 0, ImVec2(9, 1), 1.0f }, + { ImGuiKey_P, "p", "P", 0, ImVec2(10, 1), 1.0f }, + { ImGuiKey_Q, "q", "Q", 0, ImVec2(1, 1), 1.0f }, + { ImGuiKey_R, "r", "R", 0, ImVec2(4, 1), 1.0f }, + { ImGuiKey_S, "s", "S", 0, ImVec2(2, 2), 1.0f }, + { ImGuiKey_T, "t", "T", 0, ImVec2(5, 1), 1.0f }, + { ImGuiKey_U, "u", "U", 0, ImVec2(7, 1), 1.0f }, + { ImGuiKey_V, "v", "V", 0, ImVec2(4, 3), 1.0f }, + { ImGuiKey_W, "w", "W", 0, ImVec2(2, 1), 1.0f }, + { ImGuiKey_X, "x", "X", 0, ImVec2(2, 3), 1.0f }, + { ImGuiKey_Y, "y", "Y", 0, ImVec2(6, 1), 1.0f }, + { ImGuiKey_Z, "z", "Z", 0, ImVec2(1, 3), 1.0f }, + { ImGuiKey_F1, "F1", "", 1, ImVec2(2, 0), 1.0f }, + { ImGuiKey_F2, "F2", "", 1, ImVec2(3, 0), 1.0f }, + { ImGuiKey_F3, "F3", "", 1, ImVec2(4, 0), 1.0f }, + { ImGuiKey_F4, "F4", "", 1, ImVec2(5, 0), 1.0f }, + { ImGuiKey_F5, "F5", "", 1, ImVec2(6.5, 0), 1.0f }, + { ImGuiKey_F6, "F6", "", 1, ImVec2(7.5, 0), 1.0f }, + { ImGuiKey_F7, "F7", "", 1, ImVec2(8.5, 0), 1.0f }, + { ImGuiKey_F8, "F8", "", 1, ImVec2(9.5, 0), 1.0f }, + { ImGuiKey_F9, "F9", "", 1, ImVec2(11, 0), 1.0f }, + { ImGuiKey_F10, "F10","", 1, ImVec2(12, 0), 1.0f }, + { ImGuiKey_F11, "F11","", 1, ImVec2(13, 0), 1.0f }, + { ImGuiKey_F12, "F12","", 1, ImVec2(14, 0), 1.0f }, + { ImGuiKey_Apostrophe, "'", "\"", 0, ImVec2(11, 2), 1.0f }, + { ImGuiKey_Comma, ",", "<", 0, ImVec2(8, 3), 1.0f }, + { ImGuiKey_Minus, "-", "_", 0, ImVec2(11, 0), 1.0f}, + { ImGuiKey_Period, ".", ">", 0, ImVec2(9, 3), 1.0f }, + { ImGuiKey_Slash, "/", "?", 0, ImVec2(10, 3), 1.0f }, + { ImGuiKey_Semicolon, ";", ":", 0, ImVec2(10, 2), 1.0f }, + { ImGuiKey_Equal, "=", "+", 0, ImVec2(12, 0), 1.0f }, + { ImGuiKey_LeftBracket, "[", "{", 0, ImVec2(11, 1), 1.0f }, + { ImGuiKey_Backslash, "\\","|", 0, ImVec2(13, 1), 1.5f }, + { ImGuiKey_RightBracket, "]", "}", 0, ImVec2(12, 1), 1.0f }, + { ImGuiKey_GraveAccent, "`", "~", 0, ImVec2(0, 0), 1.0f }, + { ImGuiKey_CapsLock, "Caps", "", 0, ImVec2(0, 2), 1.75f }, + { ImGuiKey_ScrollLock, "\0", "", 0, ImVec2(0, 0), 1.0f }, // unused + { ImGuiKey_NumLock, "\0", "", 0, ImVec2(0, 0), 1.0f }, // + { ImGuiKey_PrintScreen, "\0", "", 0, ImVec2(0, 0), 1.0f }, // + { ImGuiKey_Pause, "\0", "", 0, ImVec2(0, 0), 1.0f }, // + { ImGuiKey_Keypad0, "0", "", 3, ImVec2(0, 4), 2.0f }, + { ImGuiKey_Keypad1, "1", "", 3, ImVec2(0, 3), 1.0f }, + { ImGuiKey_Keypad2, "2", "", 3, ImVec2(1, 3), 1.0f }, + { ImGuiKey_Keypad3, "3", "", 3, ImVec2(2, 3), 1.0f }, + { ImGuiKey_Keypad4, "4", "", 3, ImVec2(0, 2), 1.0f }, + { ImGuiKey_Keypad5, "5", "", 3, ImVec2(1, 2), 1.0f }, + { ImGuiKey_Keypad6, "6", "", 3, ImVec2(2, 2), 1.0f }, + { ImGuiKey_Keypad7, "7", "", 3, ImVec2(0, 1), 1.0f }, + { ImGuiKey_Keypad8, "8", "", 3, ImVec2(1, 1), 1.0f }, + { ImGuiKey_Keypad9, "9", "", 3, ImVec2(2, 1), 1.0f }, + { ImGuiKey_KeypadDecimal, ".", "", 3, ImVec2(2, 4), 1.0f }, + { ImGuiKey_KeypadDivide, "/", "", 3, ImVec2(1, 0), 1.0f }, + { ImGuiKey_KeypadMultiply, "*", "", 3, ImVec2(2, 0), 1.0f }, + { ImGuiKey_KeypadSubtract, "-", "", 3, ImVec2(3, 0), 1.0f }, + { ImGuiKey_KeypadAdd, "+", "", 3, ImVec2(3, 1), -2.0f }, // long keys! + { ImGuiKey_KeypadEnter, "Ent", "", 3, ImVec2(3, 3), -2.0f }, + { ImGuiKey_KeypadEqual, "", "", 3, ImVec2(0, 0), 1.0f } // unused +}; + +static char *KeyModeTitles[] = { + "All", + "Viewport", + "Timeline", + "Graph", + "Brush" +}; + +static char *KeyModText[] = { + "ERROR", + "Ctrl", + "Alt", + "Shift", + "Ctrl + Shift" +}; + +static ImVec2 SectorOffset[4] = { ImVec2(0, 1.5), ImVec2(0, 0) , ImVec2(15.5, 1.5), ImVec2(19, 1.5) }; + diff --git a/src/include/layer.h b/src/include/layer.h new file mode 100644 index 0000000..85d980d --- /dev/null +++ b/src/include/layer.h @@ -0,0 +1,50 @@ +static block_layer * +Layer_Init(project_data *File, memory *Memory); + +static void +Layer_Delete(project_data *File, project_state *State, memory *Memory, uint32 Index); + +static layer_transforms +Layer_GetTransforms(block_layer *Layer); + +static int +Layer_GetTopOffset(project_data *File, memory *Memory); + +static void +Layer_UpdateMasksEffects(project_state *State, block_layer *Layer, memory *Memory, void *EffectBitmapAddress, + int Width, int Height, int BytesPerPixel); + +static void +Layer_ToggleChannel(project_data *File, memory *Memory, int32 a); + +static void +Layer_Select(memory *Memory, project_state *State, int32 i); + +static void +Layer_Select_RecurseUp(memory *Memory, project_state *State, int32 i, int16 RecursionIdx[MAX_PRECOMP_RECURSIONS], uint32 Recursions); + +static void +Layer_DeselectAll(project_data *File, project_state *State, memory *Memory); + +static bool32 +Layer_LoopChannels(project_state *State, memory *Memory, sorted_property_array **SortedProperty, uint16 **SortedKeyframe, block_layer *Layer, + property_channel **Property, block_effect **EffectOut, int *h, int *c, int *p); + +static void +Layer_ToggleAllChannels(project_state *State, memory *Memory, block_layer *Layer, + sorted_comp_array *SortedCompStart, sorted_layer_array *SortedLayerStart, + sorted_property_array *SortedPropertyStart, uint16 *SortedKeyframeArray); + +static void +Layer_Select_Traverse(uint16 PrincipalCompIndex, memory *Memory, project_state *State, int32 IndexToFind, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, + int16 RecursionIdx[MAX_PRECOMP_RECURSIONS], int32 *Recursions); + +static v2 +Layer_TraverseForPoint(project_data *File, project_state *State, memory *Memory, v2 PrincipalCompUV, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray); + +static int32 +Layer_TestSelection(memory *Memory, project_state *State, ui *UI, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, uint16 PrincipalIndex); + +static void +Layer_RecursiveDeselect(memory *Memory, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, uint16 TargetIndex, uint16 PrincipalIndex); + diff --git a/src/include/main.h b/src/include/main.h new file mode 100644 index 0000000..3c7ff83 --- /dev/null +++ b/src/include/main.h @@ -0,0 +1,686 @@ +enum instruction_mode { + instruction_mode_scalar, +#if ARM + instruction_mode_neon, +#else + instruction_mode_sse, + instruction_mode_avx +#endif +}; + +static char* BlendmodeNames[] = { + "Normal", + "Multiply", + "Color Burn", + "Linear Burn", + "Add", + "Screen", + "Overlay", + "Soft Light", + "Hard Light", + "Subtract", + "Divide", + "Difference" +}; + +enum blend_mode +{ + blend_normal, + blend_multiply, + blend_colorburn, + blend_linearburn, + blend_add, + blend_screen, + blend_overlay, + blend_softlight, + blend_hardlight, + blend_subtract, + blend_divide, + blend_difference +}; + +#define STRING_SIZE (1024 - sizeof(uint8)) // TODO(fox): Paths above STRING_SIZE length aren't handled properly. +struct block_string { + uint8 Occupied; + char Char[STRING_SIZE]; +}; + +struct bitmap_cache_status +{ + uint32 Block_End; +}; + +enum cache_entry_type +{ + cache_entry_type_assert, + cache_entry_type_comp, + cache_entry_type_source +}; + +struct cache_entry +{ + uint8 IsOccupied; + uint8 IsCached; + uint64 CycleTime; + uint32 Block_StartIndex; + enum cache_entry_type Type; + uint32 TypeInfo; + uint32 TypeInfo_Sub; +}; + +enum interpolation_type +{ + interpolation_type_linear, + interpolation_type_bezier, + interpolation_type_hold +}; + +struct bezier_point { + uint8 Occupied; + v2 Pos[3]; + interpolation_type Type; + bool32 IsSelected; + uint8 PointSelect[3]; + uint8 Color; +}; + +struct block_bezier { + uint8 Occupied; + bezier_point Point[MAX_KEYFRAMES_PER_BLOCK]; +}; + +enum selection_type +{ + selection_type_none, + selection_type_layer, + selection_type_keyframe +}; + +struct clipboard_channel { + void *Name; + uint16 LayerOffset; + uint16 KeyframeCount; +}; + +struct clipboard_contents { + selection_type Type; + clipboard_channel Channel[16]; + uint16 ChannelCount; +}; + +struct layer_bitmap_state { + // Image and video + bool32 ToUpdate = 1; + + // GL state + // gl_effect_layer Test; + // gl_effect_layer TestM; + + // Video state + int32 CurrentFrame = -1; // The last frame number rendered to the bitmap. -1 gurantees a load upon layer creation. + void *AVInfo; // Internal data containing current frame info +}; + +struct render_state +{ + struct layer_bitmap_state Bitmap[MAX_LAYERS]; + cache_entry Entry[2048]; +}; + +struct render_queue_item +{ + bool32 Type; + v2 Pos; +}; + +struct render_queue +{ + uint16 Playhead; + uint16 CurrentIdx; + render_queue_item Item[512]; +}; + +enum focused_window +{ + focus_viewport, + focus_properties, + focus_timeline +}; + +struct sorted_property_array +{ + uint32 MinYIndex; + uint32 MaxYIndex; +}; + +struct sorted_comp_array +{ + uint32 LayerCount; + uint32 CurrentSortIndex; // Used intermediately in the sorting algorithm +}; + +struct sorted_layer_array +{ + uint16 Block_Layer_Index; + real32 SortedOffset; + uint16 Sorted_Effect_Index[MAX_EFFECTS]; + uint16 SortedPropertyStart; + uint16 SortedKeyframeStart; +}; + +struct sorted_file +{ + sorted_comp_array *CompArray; + sorted_layer_array *LayerArray; + sorted_property_array *PropertyStart; + uint16 *PropertyArray; + uint16 *SourceArray; // sorted by 'recency,' wip for stablediffusion stuff + uint16 TempSourceCount; + uint64 Layer_SortSize; + uint64 Property_SortSize; + uint64 Source_SortSize; +}; + +enum timeline_mode +{ + timeline_mode_default, + timeline_mode_graph +}; + +struct pen_state { + bool32 IsActive; +}; + +struct brush_state +{ + ImVec2 UIPos; // Initial position when ctrl is held + real32 Size = 256; // Maxes at 1024 for now + real32 Hardness = 0.55f; // From 1 to 100 + real32 Spacing = 1.0f; + bool32 EraseMode = 0; + GLuint GLTexture; + v2 PrevPos; + void *PaintBuffer; + void *TransientBitmap; + uint32 LayerToPaint_Index = -1; + rectangle CacheBounds = { 99999, 99999, -99999, -99999 }; +}; + +enum interact_type +{ + interact_type_none, + interact_type_timeline_scrub, + interact_type_slider_scrub, + interact_type_layer_move, + interact_type_layer_timeadjust, + interact_type_viewport_transform, + interact_type_keyframe_move, + interact_type_keyframe_scale, + interact_type_keyframe_rotate, + interact_type_brush +}; + +char *ToolName[] { + "Move", + "Crop", + "Brush", + "Pen" +}; + +enum tool { + tool_default, + tool_crop, + tool_brush, + tool_pen, + tool_count +}; + +struct interact_transform +{ + v2 Min; + v2 Max; + real32 Radians; + v2 Position; + real32 Scale = 1.0f; + ImVec2 OGPos; + uint32 TransformMode; +}; + +enum hotkey_input +{ + hotkey_none, + hotkey_newpaintlayer, + hotkey_newlayerfromsource, + hotkey_deletelayer, + hotkey_undo, + hotkey_redo, +}; + +enum property_display_type +{ + property_display_type_standard, + property_display_type_blendmode, + property_display_type_color +}; + +struct header_property +{ + char *Name; + real32 DefaultValue; + property_display_type DisplayType; + real32 MinVal; + real32 MaxVal; + bool32 AlwaysInteger; + +}; + +struct gl_effect_layer { + bool32 Initialized; + GLuint Texture; + GLuint FramebufferObject; + uint32 Color_Renderbuffer; + uint32 Stencil_Renderbuffer; +}; + + +enum effect_display_type +{ + effect_display_type_standard, + effect_display_type_levels, + effect_display_type_curves +}; + +struct block_effect +{ + uint8 Occupied; + char ID[8]; + bool32 IsToggled; + uint32 Block_Property_Index[MAX_PROPERTIES_PER_EFFECT]; + real32 ExtraData[16]; +}; + +struct header_effect +{ + char *Name; + char *ID; // Eight-letter string that's used in the actual file + void (*func)(real32 *, int, int, int, void *, uint16); + uint16 PropertyStartIndex; + uint16 Property_Count; + effect_display_type DisplayType; + bool32 UseGL; + uint32 GLShaderIndex; +}; + +enum imgui_popups +{ + popup_none, + popup_saveas, + popup_keybinds +}; + +struct project_state +{ + bool32 UpdateKeyframes = 0; + bool32 UpdateFrame = 1; // only refreshes frame; set UpdateKeyframes to update animation + bool32 DebugDisableCache = 1; + uint32 CachedFrameCount; + + uint64 HotFramePerf = 0; + + uint32 AVCount; + + render_state Render; + render_queue Queue; + + int32 Frame_Current; + tool Tool = tool_default; + // GLuint ToolIconTex[(int)tool_count]; + pen_state Pen = {}; + brush_state Brush; + +#if STABLE + int32 CurlActive = 0; + char JSONPayload[1024*1024*4]; + real32 SDPercentDone; + real32 SDTimeEstimate; + real64 SDTimer; +#endif + + header_effect Effect[128]; + header_property Property[512]; + uint16 Playhead_Effect; + uint16 Playhead_Property; + + int32 PreviewLayer = -1; + int32 PreviewSource = -1; + + hotkey_input HotkeyInput; + + void *Dump1; + void *Dump2; + + char DummyName[512]; + char DummyName2[512]; + + bool32 IsRunning = 1; + bool32 IsPlaying; + bool32 PlayAudio; + int32 FramePlayingCount; + bool32 FirstFrame = 1; + int32 AudioLayerIndex = -1; + + void *ClipboardBuffer; + uint64 ClipboardSize; + + int16 MostRecentlySelectedLayer = -1; + + // NOTE(fox): Try to use this only where you actually need it (the + // ambiguous case of copying keyframes versus layers), since this state + // transfer will get buggy if you expand it to everything. + selection_type RecentSelectionType = selection_type_none; + + interact_type Interact_Active; + int32 Interact_Modifier; + real32 Interact_Offset[12]; + void *Interact_Address; + + int32 Initializing = 3; + + int32 MsgTime; // currently in "frames" + char *Msg; + + imgui_popups ImGuiPopups; + char Filename[512]; + + ImGuiTextFilter filter; // This filter API is pretty ballin'. + bool32 RerouteEffects; // Allows shift+space hotkey to gain focus on the effects panel. + + ImDrawListSplitter Test; + ImDrawListSplitter Split_KeybindUI; + + int32 Warp_X = 0; + int32 Warp_Y = 0; + bool32 Warp_WantSetPos = false; + ImVec2 Warp_PositionToSet; + real32 Warp_PositionInitial; + int32 Warp_Direction; + + uint32 InteractTransformMode; // Whether a drag on the Shift+T UI is scale (1), rotation (2), or position (3). + + timeline_mode TimelineMode; + + bool32 BoxSelect; + + focused_window FocusedWindow; // Convenience for adding window-specific hotkeys. + bool32 SetFocus; + v2 TempZoomRatio = V2(1, 1); +}; + +// UI info that's saved to the file and is not part of the history tree +struct ui +{ + ImVec2 CompZoom; // In screen pixels, not percentage. + ImVec2 CompPos; + + // Under 1 is zoomed in! + ImVec2 TimelinePercentZoomed; + ImVec2 TimelinePercentOffset; + + ImVec2 GraphZoomSize; + ImVec2 GraphMoveSize; + + v4 Color = {1, 1, 1, 1}; + v4 AltColor = {0, 0, 0, 1}; + bool32 IsPrimary; + +#if STABLE + sd_state SD; + bool32 StableEnabled = 0; +#endif + + ImU32 LayerColors[16] = { + 0xff8b1f1f, + 0xffc25909, + 0xff57c20a, + 0xff8ee6da, + 0xffa48fb7, + 0xffd14061, + 0xff38b683, + 0xff3fdbe5, + 0xffc9c9c9, + 0xff978489, + 0xfffaf5ab, + 0xff101010, + 0xffa024ca, + 0xfffae920, + 0xff208dfa, + 0xfffa2051 + }; +}; + + +struct project_data +{ + uint8 Occupied; + uint16 Layer_Count; + uint16 Source_Count; + uint16 Comp_Count; + uint16 PrincipalCompIndex; + ui UI; +}; + +struct block_composition +{ + uint8 Occupied; + + uint16 Name_String_Index; + + uint16 Width; + uint16 Height; + uint16 BytesPerPixel; + uint16 FPS; + + uint32 Frame_Count; + int32 Frame_Start; + int32 Frame_End; +}; + +struct layer_transforms +{ + real32 x; + real32 y; + real32 ax; + real32 ay; + real32 rotation; + real32 scale; +}; + +enum source_type { + source_type_none, + source_type_principal, + source_type_principal_temp, + source_type_file +}; + +struct block_source +{ + uint8 Occupied; + + bool32 IsSelected; + + uint16 Path_String_Index; + uint16 Name_String_Index; + + // Only used for type_principal + uint16 Bitmap_Index; + + uint16 Width; + uint16 Height; + uint16 BytesPerPixel; + + // LibAV specific + real32 FPS; + bool32 HasAudio; + bool32 HasVideo; + + uint32 RelativeTimestamp; + GLuint ThumbnailTex; + + source_type Type; +}; + +struct property_channel { + uint8 Occupied; + uint16 Block_Bezier_Index[MAX_KEYFRAME_BLOCKS]; + uint16 Block_Bezier_Count; + uint16 Keyframe_Count; + + int32 Identifier; + + real32 CurrentValue; + real32 MaxVal; + real32 MinVal; + bool32 AlwaysInteger; + real32 ScrubVal; // increment when dragging on sliders, etc. + + bool32 IsToggled; +}; + +char *DefaultChannel[] = { "X Position", "Y Position", "Anchor X", "Anchor Y", + "Rotation", "Scale", "Opacity", "Frame Number" }; + +struct block_layer { + uint8 Occupied; + + bool32 IsPrecomp; + bool32 Precomp_Toggled; + uint16 Block_Source_Index; // also used for precomp + uint16 Block_String_Index; + uint16 Block_Composition_Index; + + uint16 Block_Mask_Index[MAX_MASKS]; + uint16 Block_Mask_Count; + + uint16 Block_Effect_Index[MAX_EFFECTS]; + uint16 Block_Effect_Count; + + blend_mode BlendMode; + + union + { + property_channel Property[8]; + struct + { + property_channel x; + property_channel y; + property_channel ax; + property_channel ay; + property_channel rotation; + property_channel scale; + property_channel opacity; + property_channel time; + }; + }; + + bool32 IsSelected; + bool32 IsVisible; + bool32 IsAdjustment; + + int32 Frame_Start; + int32 Frame_End; + + real32 Vertical_Offset; + real32 Vertical_Height = 1; + + uint16 ColIndex; +}; + +struct render_byte_info { + uint32 MaskPixel; + uint32 ByteOffset; + uint32 Bits; + real32 Normalized; +}; + +struct transform_info { + real32 XAxisPX; + real32 XAxisPY; + real32 YAxisPX; + real32 YAxisPY; + + real32 LayerWidth; + real32 LayerHeight; + real32 LayerBytesPerPixel; + real32 LayerPitch; + render_byte_info LayerBits; + + real32 BufferWidth; + real32 BufferHeight; + real32 BufferBytesPerPixel; + real32 BufferPitch; + render_byte_info BufferBits; + + real32 LayerOpacity; + real32 OriginX; + real32 OriginY; + blend_mode BlendMode; + + bool32 IsAdjustment; + + rectangle ClipRect; + void *SourceBuffer; +}; + +struct direct_info { + real32 BufferWidth; + real32 BufferHeight; + real32 BufferBytesPerPixel; + real32 BufferPitch; + render_byte_info BufferBits; + + real32 Opacity; + + blend_mode BlendMode; + rectangle ClipRect; + void *SourceBuffer; + + bool32 SwapActive; + bool32 OnlyBlendAlpha; +}; + +struct brush_info { + uint32 BrushLength; + rectangle LayerBounds; + uint32 LayerPitch; + uint32 BrushPitch; + int32 ExtraX; + int32 ExtraY; + render_byte_info LayerBits; + render_byte_info BrushBits; + int BytesPerPixel; + int SourceWidth; + int SourceBytesPerPixel; + void *SourceBuffer; + void *BrushBuffer; + real32 R_Brush; + real32 G_Brush; + real32 B_Brush; + real32 A_Brush; + bool32 EraseMode; + uint8 *BrushRow; +}; + +enum render_type { + render_type_main, + render_type_notransform, + render_type_notransform_swap, + render_type_brush +}; + +struct render_entry { + void *RenderData; + void *OutputBuffer; + render_type RenderType; + rectangle RenderRegion; +}; + diff --git a/src/include/memory.h b/src/include/memory.h new file mode 100644 index 0000000..dab6ed4 --- /dev/null +++ b/src/include/memory.h @@ -0,0 +1,71 @@ +enum memory_table_list { + + P_AVInfo, + P_UndoBuffer, + P_MiscCache, + + F_File, + F_Precomps, + F_Layers, + F_Sources, + F_Properties, + F_Bezier, + F_Effects, + F_Strings, + F_PrincipalBitmaps, + + B_Thumbnails, + B_ScratchSpace, + B_CacheEntries, + B_CachedBitmaps, +}; + +struct memory_table { + char *Name; + void *Address; + uint64 Size; + uint32 Block_ElementSize; +}; + +struct global_memory { + void *Address; + uint64 CurrentPosition; + uint64 Size; +}; + +enum history_action_type { + action_type_swap, + action_type_swap_bitmap, + action_type_shift +}; + +struct history_action { + memory_table_list TableName; + history_action_type Type; + uint64 Size; + uint64 ByteOffset; + uint64 ShiftAmount; // Only for type_shift + int16 Direction; // Only for type_shift +}; + +struct history_entry { + char *Name; + uint16 NumberOfActions; +}; + +struct history_entry_list { + history_entry Entry[256]; + history_action Action[1024]; + uint16 NumberOfEntries; + uint16 EntryPlayhead; +}; + +struct memory { + memory_table Slot[16]; + history_entry_list History; + uint64 ScratchPos; + uint32 EntryCount; + bool32 IsFileSaved; + bool32 PurgeCache; +}; + diff --git a/src/include/my_math.h b/src/include/my_math.h new file mode 100644 index 0000000..92d43b7 --- /dev/null +++ b/src/include/my_math.h @@ -0,0 +1,762 @@ +#define PI 3.141592653589793238 + +union v2 +{ + struct + { + real32 x, y; + }; + real32 E[2]; +}; + +union v2i +{ + struct + { + int32 x, y; + }; + int32 E[2]; +}; + +union v3 +{ + struct + { + real32 r, g, b; + }; + int32 E[3]; +}; + +union v4 +{ + struct + { + real32 r, g, b, a; + }; + real32 E[4]; +}; + +inline v2 V2(real32 x, real32 y) +{ + v2 Result; + + Result.x = x; + Result.y = y; + + return(Result); +} + +inline v2 V2(real32 x) +{ + v2 Result; + + Result.x = x; + Result.y = x; + + return(Result); +} + +inline v2 V2(ImVec2 A) +{ + v2 Result; + + Result.x = A.x; + Result.y = A.y; + + return(Result); +} + +inline ImVec2 V2(v2 A) +{ + struct ImVec2 Result; + + Result.x = A.x; + Result.y = A.y; + + return(Result); +} + +inline v2i V2i(int32 x, int32 y) +{ + v2i Result; + + Result.x = x; + Result.y = y; + + return(Result); +} + +inline v3 V3(real32 a) +{ + v3 Result; + + Result.r = a; + Result.g = a; + Result.b = a; + + return(Result); +} + +inline v4 V4(real32 r) +{ + v4 Result; + + Result.r = r; + Result.g = r; + Result.b = r; + Result.a = r; + + return(Result); +} + +inline v4 powv4(v4 Col, real32 i) +{ + v4 Result; + + Result.r = pow(Col.r, i); + Result.g = pow(Col.g, i); + Result.b = pow(Col.b, i); + Result.a = pow(Col.a, i); + + return(Result); +} + +inline v4 powv4(v4 Col, v4 i) +{ + v4 Result; + + Result.r = pow(Col.r, i.r); + Result.g = pow(Col.g, i.g); + Result.b = pow(Col.b, i.b); + Result.a = pow(Col.a, i.a); + + return(Result); +} + +inline v4 V4(v3 r, real32 a) +{ + v4 Result; + + Result.r = r.r; + Result.g = r.g; + Result.b = r.b; + Result.a = a; + + return(Result); +} + +inline v4 V4(real32 r, real32 g, real32 b, real32 a) +{ + v4 Result; + + Result.r = r; + Result.g = g; + Result.b = b; + Result.a = a; + + return(Result); +} + +inline v4 ClipV4(v4 A) +{ + v4 Result; + if (A.r < 0.0f) { + Result.r = 0.0f; + } else if (A.r > 1.0f) { + Result.r = 1.0f; + } else { + Result.r = A.r; + } + + if (A.g < 0.0f) { + Result.g = 0.0f; + } else if (A.g > 1.0f) { + Result.g = 1.0f; + } else { + Result.g = A.g; + } + + if (A.b < 0.0f) { + Result.b = 0.0f; + } else if (A.b > 1.0f) { + Result.b = 1.0f; + } else { + Result.b = A.b; + } + + if (A.a < 0.0f) { + Result.a = 0.0f; + } else if (A.a > 1.0f) { + Result.a = 1.0f; + } else { + Result.a = A.a; + } + + return(Result); +} + + +v2i operator+(v2i A, v2i B) +{ + v2i Result; + + Result.x = A.x + B.x; + Result.y = A.y + B.y; + + return(Result); +} + +v2 operator/(v2 A, real32 B) +{ + v2 Result; + + Result.x = A.x / B; + Result.y = A.y / B; + + return Result; +} + + + +v4 operator+(v4 A, v4 B) +{ + v4 Result; + + Result.r = A.r + B.r; + Result.g = A.g + B.g; + Result.b = A.b + B.b; + Result.a = A.a + B.a; + + return(Result); +} + +v4 operator-(v4 A, v4 B) +{ + v4 Result; + + Result.r = A.r - B.r; + Result.g = A.g - B.g; + Result.b = A.b - B.b; + Result.a = A.a - B.a; + + return(Result); +} + +v4 operator-(real32 A, v4 B) +{ + v4 Result; + + Result.r = A - B.r; + Result.g = A - B.g; + Result.b = A - B.b; + Result.a = A - B.a; + + return(Result); +} + +v4 operator-(v4 A, real32 B) +{ + v4 Result; + + Result.r = A.r - B; + Result.g = A.g - B; + Result.b = A.b - B; + Result.a = A.a - B; + + return(Result); +} + +v4 operator*(v4 A, v4 B) +{ + v4 Result; + + Result.r = A.r * B.r; + Result.g = A.g * B.g; + Result.b = A.b * B.b; + Result.a = A.a * B.a; + + return(Result); +} + +v4 operator/(v4 A, v4 B) +{ + v4 Result; + + Result.r = A.r / B.r; + Result.g = A.g / B.g; + Result.b = A.b / B.b; + Result.a = A.a / B.a; + + return(Result); +} + +v4 operator/(real32 A, v4 B) +{ + v4 Result; + + Result.r = A / B.r; + Result.g = A / B.g; + Result.b = A / B.b; + Result.a = A / B.a; + + return(Result); +} + +v4 operator*(v4 A, real32 B) +{ + v4 Result; + + Result.r = A.r * B; + Result.g = A.g * B; + Result.b = A.b * B; + Result.a = A.a * B; + + return(Result); +} + +v4 operator*(real32 B, v4 A) +{ + v4 Result; + + Result.r = A.r * B; + Result.g = A.g * B; + Result.b = A.b * B; + Result.a = A.a * B; + + return(Result); +} + +v2 operator-(v2 A, v2i B) +{ + v2 Result; + + Result.x = A.x - (real32)B.x; + Result.y = A.y - (real32)B.y; + + return(Result); +} + +v2 operator/(v2 A, v2 B) +{ + v2 Result; + + Result.x = A.x / B.x; + Result.y = A.y / B.y; + + return(Result); +} + +v2i operator-(v2i A, v2i B) +{ + v2i Result; + + Result.x = A.x - B.x; + Result.y = A.y - B.y; + + return(Result); +} + +v2i operator-(v2i A, int16 B) +{ + v2i Result; + + Result.x = A.x - B; + Result.y = A.y - B; + + return(Result); +} + +v2i operator+(v2i A, int16 B) +{ + v2i Result; + + Result.x = A.x + B; + Result.y = A.y + B; + + return(Result); +} + +v2 operator*(real32 A, v2 B) +{ + v2 Result; + + Result.x = A * B.x; + Result.y = A * B.y; + + return(Result); +} + +v2 operator*(v2 A, real32 B) +{ + v2 Result; + + Result.x = A.x * B; + Result.y = A.y * B; + + return(Result); +} + + +v2 operator-(v2 A, v2 B) +{ + v2 Result; + + Result.x = A.x - B.x; + Result.y = A.y - B.y; + + return(Result); +} + +v2 operator-(v2 A, real32 B) +{ + v2 Result; + + Result.x = A.x - B; + Result.y = A.y - B; + + return(Result); +} + +v2 operator-(v2 A) +{ + v2 Result; + + Result.x = -A.x; + Result.y = -A.y; + + return(Result); +} + +v2 operator+(v2 A, v2 B) +{ + v2 Result; + + Result.x = A.x + B.x; + Result.y = A.y + B.y; + + return(Result); +} + +v2 operator*(v2 A, v2 B) +{ + v2 Result; + + Result.x = A.x * B.x; + Result.y = A.y * B.y; + + return(Result); +} + +struct rectangle +{ + v2i Min; + v2i Max; +}; + +inline real32 +Min(real32 A, real32 B) +{ + return (A > B) ? B : A; +} + +inline real32 +Max(real32 A, real32 B) +{ + return (A > B) ? A : B; +} + +inline bool32 +TestRectangle(rectangle Rect, v2i Test) +{ + bool32 Result = (Test.x > Rect.Min.x && Test.x < Rect.Max.x && + Test.y > Rect.Min.y && Test.y < Rect.Max.y); + return(Result); +} + +inline bool32 +TestRectangle(ImVec2 Min, ImVec2 Max, ImVec2 Test) +{ + bool32 Result = (Test.x > Min.x && Test.x < Max.x && + Test.y > Min.y && Test.y < Max.y); + return(Result); +} + +inline rectangle +ClipRectangle(rectangle Rect, rectangle BoundRect) +{ + if(Rect.Min.x < BoundRect.Min.x) + { + Rect.Min.x = BoundRect.Min.x; + } + if(Rect.Min.y < BoundRect.Min.y) + { + Rect.Min.y = BoundRect.Min.y; + } + if(Rect.Max.x > BoundRect.Max.x) + { + Rect.Max.x = BoundRect.Max.x; + } + if(Rect.Max.y > BoundRect.Max.y) + { + Rect.Max.y = BoundRect.Max.y; + } + return(Rect); +} + +inline rectangle +VerifyMinMax(rectangle Rect) +{ + if(Rect.Min.x > Rect.Max.x) + { + int16 Temp = Rect.Max.x; + Rect.Max.x = Rect.Min.x; + Rect.Min.x = Temp; + } + if(Rect.Min.y > Rect.Max.y) + { + int16 Temp = Rect.Max.y; + Rect.Max.y = Rect.Min.y; + Rect.Min.y = Temp; + } + return(Rect); +} + +inline int32 +RoundReal32ToInt32(real32 Real32) +{ + int32 Result = (int32)(Real32 + 0.5f); + return(Result); +} + +inline uint32 +RoundReal32ToUint32(real32 Real32) +{ + uint32 Result = (uint32)(Real32 + 0.5f); + return(Result); +} + +inline uint32 +ColToUint32(real32 B) +{ + uint32 Result = ((RoundReal32ToUint32(1 * 255.0f) << 24) | + (RoundReal32ToUint32(B * 255.0f) << 16) | + (RoundReal32ToUint32(B * 255.0f) << 8) | + (RoundReal32ToUint32(B * 255.0f) << 0)); + return Result; +} + +inline uint32 +ColToUint32(v4 Col) +{ + uint32 Result = ((RoundReal32ToUint32(Col.a * 255.0f) << 24) | + (RoundReal32ToUint32(Col.r * 255.0f) << 16) | + (RoundReal32ToUint32(Col.g * 255.0f) << 8) | + (RoundReal32ToUint32(Col.b * 255.0f) << 0)); + return Result; +} + +inline real32 +Square(real32 A) +{ + real32 Result = A * A; + return Result; +} + +inline real32 +Inner(v2 A, v2 B) +{ + real32 Result = A.x * B.x + A.y * B.y; + + return Result; +} + +inline real32 +Inner(ImVec2 A, ImVec2 B) +{ + real32 Result = A.x * B.x + A.y * B.y; + + return Result; +} + +inline real32 +LengthSq(v2 A) +{ + real32 Result = Inner(A, A); + return Result; +} + +inline uint32 +Floor(uint32 A, uint32 B) +{ + if (A < B) { + A = B; + } + return A; +} + +inline uint32 +Ceil(uint32 A, uint32 B) +{ + if (A > B) { + A = B; + } + return A; +} + +inline real32 +Floor(real32 A, real32 B) +{ + if (A < B) { + A = B; + } + return A; +} + +inline real32 +Ceil(real32 A, real32 B) +{ + if (A > B) { + A = B; + } + return A; +} + +inline bool32 +TestUV(v2 UV) { + return (UV.x <= 1.0f && UV.x >= 0.0f && UV.y <= 1.0f && UV.y >= 0.0f); +} + +inline real32 +Clamp(real32 A, real32 B, real32 C) +{ + if (B < A) { + B = A; + } + if (B > C) { + B = C; + } + return B; +} + +inline v4 +Clamp(real32 A, v4 B, real32 C) +{ + B.r = Clamp(A, B.r, C); + B.g = Clamp(A, B.g, C); + B.b = Clamp(A, B.b, C); + B.a = Clamp(A, B.a, C); + return B; +} + + + +inline v4 +Lerp(v4 A, real32 t, v4 B) +{ + v4 Result = (1.0f - t)*A + t*B; + + return Result; +} + +inline v4 +Uint32ToCol(uint32 LayerPixel) +{ + uint8 A2 = (LayerPixel >> 24); + uint8 R2 = (LayerPixel >> 16); + uint8 G2 = (LayerPixel >> 8); + uint8 B2 = (LayerPixel >> 0); + v4 Color = {(real32)R2 / 255.0f, + (real32)G2 / 255.0f, + (real32)B2 / 255.0f, + (real32)A2 / 255.0f}; + return Color; +} + +inline v4 +Uint32ToCol8(uint32 LayerPixel) +{ + uint8 A2 = (LayerPixel >> 24); + uint8 B2 = (LayerPixel >> 16); + uint8 G2 = (LayerPixel >> 8); + uint8 R2 = (LayerPixel >> 0); + v4 Color = {(real32)R2, + (real32)G2, + (real32)B2, + (real32)A2}; + return Color; +} + +inline v4 +Uint32ToNormalizedCol(uint32 LayerPixel) +{ + uint8 A2 = (LayerPixel >> 24); + uint8 R2 = (LayerPixel >> 16); + uint8 G2 = (LayerPixel >> 8); + uint8 B2 = (LayerPixel >> 0); + + real32 R = R2 / 255.0f; + real32 G = G2 / 255.0f; + real32 B = B2 / 255.0f; + real32 A = A2 / 255.0f; + + v4 Result = {R,G,B,A}; + + return Result; +} + +inline real32 +Uint32ToNormalizedBW(uint32 LayerPixel) +{ + uint8 R2 = (LayerPixel >> 16); + uint8 G2 = (LayerPixel >> 8); + uint8 B2 = (LayerPixel >> 0); + + real32 R = R2 / 255.0f; + real32 G = G2 / 255.0f; + real32 B = B2 / 255.0f; + + real32 Result = (R + G + B) / 3.0f; + + return Result; +} + +inline uint32 +Col8ToUint32(v4 P) +{ + uint8 A2 = P.a; + uint8 R2 = P.r; + uint8 G2 = P.g; + uint8 B2 = P.b; + uint32 Result = ((A2 << 24) | + (R2 << 16) | + (G2 << 8) | + (B2 << 0)); + return Result; +} + + +inline uint8 +ClipAdd(uint8 a, uint8 b) +{ + uint8 Result = 0; + int16 exp = (int16)a + b; + if (exp > 255) { + Result = 255; + } else if (exp < 0) { + Result = 0; + } else { + Result = a + b; + } + return Result; +} + +inline real32 Normalize(real32 A) +{ + if (A > 1) { + A = 1.0f; + } else if (A < 0.0f) { + A = 0.0f; + } + return A; +} + diff --git a/src/include/sharebuffer.h b/src/include/sharebuffer.h new file mode 100644 index 0000000..c25deb2 --- /dev/null +++ b/src/include/sharebuffer.h @@ -0,0 +1,17 @@ +#include +#include +#include +#include +#include +#include +#include + +#define SHAREDMEMORY_SIZE ((uint64_t)20*1024*1024) + +struct SharedMemoryInfo { + sem_t sem1; + sem_t sem2; + int16_t shared_framenumber; + char BitmapData; +}; + diff --git a/src/include/stable_diffusion.h b/src/include/stable_diffusion.h new file mode 100644 index 0000000..3335796 --- /dev/null +++ b/src/include/stable_diffusion.h @@ -0,0 +1,33 @@ + + +// curl -X POST -H 'Content-Type: application/json' -i 'http://127.0.0.1:7860/sdapi/v1/txt2img' --data '{ +// "prompt": "cute dinosaur sticker with polka dots", +// "steps": 50, +// "sampler_index": "DDIM" +// }' + +#define SD_LEN_PROMPT 256 +#define SD_LEN_ADDRESS 128 + +// struct sd_mode +// { +// sd_mode_txt2txt, +// sd_mode_txt2img +// } + +struct sd_state +{ + bool32 Mode = 1; + char Prompt[256]; + char NegPrompt[256]; + char ServerAddress[128]; + int32 Steps = 10; + int32 Width = 512; + int32 Height = 512; + int32 SamplerIndex = 0; + real32 CFG = 7; + int32 BatchSize = 1; + real32 DenoisingStrength = 0.4; + int32 Seed = -1; +}; + diff --git a/src/include/structs.h b/src/include/structs.h new file mode 100644 index 0000000..fbb97ed --- /dev/null +++ b/src/include/structs.h @@ -0,0 +1,5 @@ +struct effect; + +struct action_entry; +struct action_entries; + diff --git a/src/include/undo.h b/src/include/undo.h new file mode 100644 index 0000000..139597f --- /dev/null +++ b/src/include/undo.h @@ -0,0 +1,2 @@ + + -- cgit v1.2.3