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, cache_entry_type_layer, }; 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_none, selection_layer, selection_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]; }; enum focused_window { focus_viewport, focus_properties, focus_timeline }; struct sorted_property_info { uint32 MinYIndex; uint32 MaxYIndex; bool32 IsGraphSelected; }; struct sorted_comp_info { uint32 LayerCount; uint32 CurrentSortIndex; // Used intermediately in the sorting algorithm }; struct sorted_layer { uint16 Block_Layer_Index; real32 SortedOffset; }; struct sorted_file { sorted_layer *LayerArray; sorted_comp_info *CompArray; sorted_property_info *PropertyInfo; uint16 *PropertyArray; uint16 *SourceArray; // sort by recency, temp only 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; }; enum brush_type { brush_normal, brush_wacky1, brush_wacky2, brush_wacky3, brush_amount }; char *BrushNames[brush_amount] = { "brush_normal", "brush_wacky1", "brush_wacky2", "brush_wacky3" }; struct brush_state { ImVec2 UIPos; // Initial position when ctrl is held real32 Size = 64; // Maxes at 1024 for now real32 Hardness = 1.0f; // From 1 to 100 real32 Spacing = 1.0f; bool32 EraseMode = 0; brush_type Type = brush_normal; GLuint GLTexture; 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_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_transform, hotkey_copy, hotkey_paste }; 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; uint16 Index; uint32 Block_Property_Index[MAX_PROPERTIES_PER_EFFECT]; }; 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; render_state Render; 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 FirstFrame = 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_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; 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; sd_state SD; bool32 StableEnabled = 0; 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 FPS; uint16 BytesPerPixel; uint32 Frame_Count; int32 Frame_Start; int32 Frame_End; }; enum source_type { source_type_none, source_type_principal, source_type_principal_temp, source_type_file }; struct layer_transforms { real32 x; real32 y; real32 ax; real32 ay; real32 rotation; real32 scale; }; 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; uint32 RelativeTimestamp; // GLuint ThumbnailTex; source_type Type; }; struct property_channel { uint8 Occupied; char *Name; // TODO(fox): Delete this. uint16 Block_Bezier_Index[MAX_KEYFRAME_BLOCKS]; uint16 Block_Bezier_Count; uint16 Keyframe_Count; 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_Offset; 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; blend_mode BlendMode; rectangle ClipRect; void *SourceBuffer; bool32 SwapActive; }; 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 *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; }; #if 0 struct cached_bitmap { uint32 SourceIndex; // Which source it belongs to. Currently used to dereference the bitmap. void *Data; // Unpacked data loaded from the source file. uint32 Frame; // What frame it is. }; struct gl_effect_layer { bool32 Initialized; GLuint Texture; GLuint FramebufferObject; uint32 Color_Renderbuffer; uint32 Stencil_Renderbuffer; }; // Bitmaps from files are loaded into these temporary cache blocks. // NOTE(fox): I use the term "comp" (composition) to mean the canvas that is // being rendered to, since it's what I'm used to from AE. struct comp_buffer { uint16 Width; uint16 Height; uint16 BytesPerPixel; void *PackedBuffer; void *UnpackedBuffer; }; struct mask_point { v2 Pos; bool32 HandleBezier; bool32 IsSelected; v2 TangentLeft; v2 TangentRight; }; struct mask { mask_point Point[16]; bool32 IsClosed; uint16 NumberOfPoints; uint16 NumberOfSelectedPoints; void *TriangulatedPointCache; uint32 NumberOfVerts; }; struct main_sdl { SDL_Texture *Texture; SDL_Event Event; SDL_Window *Window; SDL_Renderer *Renderer; }; char *ToolName[] { "Move", "Pen" }; enum tool { tool_default, tool_pen, tool_count }; struct pen_state { bool32 IsActive; }; struct brush_tool { real32 Size; real32 Opacity; real32 Hardness; }; enum focused_window { focus_viewport, focus_properties, focus_timeline }; struct ui_graph { property_channel *ChannelViewed; real32 WindowYOffset = 300; real32 UpperVal; real32 LowerVal; uint16 GraphWindowHeight; // The size of the window enclosing the graph }; struct ui { real32 TimelineSplit = 600; real32 GraphPropsSplit = 200; real32 TimelineZoom; real32 GraphZoom = 30; // Under 1 is zoomed in! real32 TimelinePercentZoomed = 1.0f; real32 TimelinePercentOffset = 0.3f; real32 Default_Y_TimelinePercentZoomed = 1.2f; real32 Default_Y_TimelinePercentOffset = 0.0f; real32 Y_TimelinePercentZoomed; real32 Y_TimelinePercentOffset; bool32 IsDragging; bool32 IsTransforming; int32 Wrap_X = 0; int32 Wrap_Y = 0; real32 TempVal; real32 TempVal_X; real32 OldVal[4]; real32 Y_MaxVal; real32 Y_MinVal; real32 Display_Y_MaxVal; real32 Display_Y_MinVal; bool32 WantSetPos = false; ImVec2 SetPos; real32 InitPos; int32 WrapDirection; // Note that I don't use "zoom" to mean the scale in relation to the // original (i.e. default = 1.0f); it's the literal screen size in pixels // of the composition in the UI. ImVec2 CompZoom; ImVec2 CompPos; // Used to set UI values on the first frame. Some UI setup in Docking takes // more than 1 frame for some reason, so I'm temporarily extending it. bool32 Initializing = 4; // Custom scrolling for the timeline, as ImGui's didn't work well real32 ScrollXOffset; real32 ScrollYOffset; // Custom scrolling for the timeline, as ImGui's didn't work well real32 G_ScrollXOffset; real32 G_ScrollYOffset; // NOTE(fox): Keeping track of mouse delta myself since the ImGui threshold // dragging API doesn't let you do things like subtract the delta easily. real32 DraggingKeyframeThreshold; real32 DraggingLayerThreshold; real32 DraggingTimelineThreshold; real32 DraggingEffectThreshold; real32 KeyframeSpacing = 6; ImVec2 BoxStart = ImVec2(0,0); ImVec2 BoxEnd = ImVec2(0,0); bool32 BoxSelectActive = false; // Temporary varibles used when zooming in/out v2 TempZoomRatio = V2(1, 1); real32 TempZoomRatioTimeline = 0; real32 TempZoomRatioGraph = 0; focused_window FocusedWindow; // Convenience for adding window-specific hotkeys. ui_graph Graph[4]; uint16 NumberOfGraphsEnabled; bool32 TemporaryUpdateOverride; }; struct imgui_buttonstate { bool32 IsItemHovered; bool32 IsItemActive; bool32 IsItemActivated; bool32 IsItemDeactivated; bool32 LeftClick; bool32 RightClick; }; struct timeline_properties { rectangle Timeline; v2i MainWindow; uint16 WindowPadding; rectangle EffectPanel; rectangle Toolbar; rectangle ColorPanel; bool32 RenderSlidingBrush; uint16 CompX; uint16 CompY; uint16 TimelineZoom; uint16 CompScale; uint16 FramePadding; uint16 LayerPadding; uint16 TimelineCurrentFrame; int16 TimelineCurrentLayer; // Signed as a shortcut for invalid on -1 uint16 InfoTimelineSplit; bool32 DrawTimeline; bool32 DrawEffectPanel; bool32 DrawComp; }; struct sdl_button { bool32 IsDown; bool32 SingleClick; // More precisely, when button is released and no dragging/selecting events are happening. int HeldLength; }; struct sdl_input { v2i Mouse; sdl_button MouseButton[3]; rectangle Selection; }; struct render_queue { project_data *File; project_state *State; comp_buffer *CompBuffer; }; struct thread_info { render_queue *RenderInfo; uint16 Index; }; struct work_queue_entry { char *StringToPrint; }; struct render_entry { rectangle RenderRegion; }; #endif