From 375c120d30456738897c4bd775e38aa1db7d239c Mon Sep 17 00:00:00 2001 From: Fox Caminiti Date: Thu, 22 Dec 2022 13:29:02 -0500 Subject: v3.1 --- src/createcalls.cpp | 5 +-- src/ffmpeg_backend.cpp | 42 +++---------------- src/imgui_helper_internal.cpp | 32 ++++++++++++++- src/imgui_ui.cpp | 7 ++++ src/imgui_ui_debug.cpp | 2 +- src/imgui_ui_properties.cpp | 6 +-- src/imgui_ui_timeline.cpp | 78 +++++++++++++++++++----------------- src/include/imgui_internal_widgets.h | 1 + src/include/main.h | 12 +++++- src/main.cpp | 74 ++++++++++++++++++++++------------ src/memory.cpp | 2 + src/sorted.cpp | 12 ++++-- 12 files changed, 162 insertions(+), 111 deletions(-) (limited to 'src') diff --git a/src/createcalls.cpp b/src/createcalls.cpp index d3c7da4..8b0ebf7 100644 --- a/src/createcalls.cpp +++ b/src/createcalls.cpp @@ -529,11 +529,10 @@ void Effect_Curves_Sort(memory *Memory, block_effect *Effect, uint16 *SortedPoin static void Interact_Evaluate_Layer(memory *Memory, project_state *State, uint16 Layer_Index_Physical, sorted_comp_array SortedCompStart, sorted_layer_array *SortedLayerStart, - int32 *Frame_Start, int32 *Frame_End) + int32 *Frame_Start, int32 *Frame_End, int *Frame_Offset) { if (State->Interact_Active == interact_type_layer_move) { - *Frame_Start += (int32)(State->Interact_Offset[0] + 0); - *Frame_End += (int32)(State->Interact_Offset[0] + 0); + *Frame_Offset += (int32)(State->Interact_Offset[0] + 0); } if (State->Interact_Active == interact_type_layer_timeadjust) { int Side[2] = {0}; diff --git a/src/ffmpeg_backend.cpp b/src/ffmpeg_backend.cpp index 821afce..a104714 100644 --- a/src/ffmpeg_backend.cpp +++ b/src/ffmpeg_backend.cpp @@ -253,7 +253,7 @@ void AV_Init(block_source *Source, av_info *AV, memory *Memory) avcodec_flush_buffers(AV->Audio.CodecContext); }; -uint32 AV_AudioTest(av_info *AV, void *Data, uint32 Size) +uint32 AV_AudioTest(av_info *AV, void *Data, uint32 Size, real32 FPS, int32 InitialFrameToSeek) { AVChannelLayout ChannelLayout = {}; av_channel_layout_default(&ChannelLayout, 2); @@ -261,12 +261,16 @@ uint32 AV_AudioTest(av_info *AV, void *Data, uint32 Size) av_stream_info *Stream = &AV->Audio; Assert(Stream->CodecContext->ch_layout.nb_channels == 2); + real32 TotalFrames = AV->SecondCount * FPS; + int64 SeekPTS = (int64)(((real64)InitialFrameToSeek / TotalFrames) * AV->PTSDuration); + int64 AveragePTS = AV->PTSDuration / TotalFrames; + int32 err = 0; bool32 EndOfFile = 0; while (err >= 0) { if (AV_TryFrame(AV, Stream->CodecContext, &err, &EndOfFile, Stream->Index)) { - if (AV->Frame->pts < Stream->Stream->start_time) { + if (AV->Frame->pts < Stream->Stream->start_time || AV->Frame->pts < SeekPTS) { av_frame_unref(AV->Frame); continue; } @@ -309,40 +313,6 @@ void AV_SeekAudio(av_info *AV, real32 FPS, int32 FrameToSeek) Assert(FrameToSeek > -1) int64 SeekSeconds = (int64)(FrameToSeek / (int32)(FPS + 0.5f) * AV_TIME_BASE); av_seek_frame(AV->FileFormatContext, -1, SeekSeconds, AVSEEK_FLAG_BACKWARD); - - /* - real32 TotalFrames = AV->SecondCount * FPS; - int64 SeekPTS = (int64)(((real64)FrameToSeek / TotalFrames) * AV->PTSDuration); - int64 AveragePTS = AV->PTSDuration / TotalFrames; - - int32 err = 0; - bool32 EndOfFile = 0; - while (err >= 0) { - if (AV_TryFrame(AV, AV->Audio.CodecContext, &err, &EndOfFile)) - { - int a = 0; - } - } - - while (err >= 0) { - if (AV_TryFrame(AV, AV->Audio.CodecContext, &err, &EndOfFile, AV->Audio.Index)) - { - // The first frame that gets loaded isn't always the actual - // first frame, so we need to check until it's correct. - if (FrameToSeek == 0 && AV->Frame->pts < AV->Audio.Stream->start_time) { - av_frame_unref(AV->Frame); - // printf("NON-START: avg: %li, real pts: %li", SeekPTS, AV->VideoFrame->pts); - continue; - } - - int64 Difference = AV->Frame->pts - SeekPTS; - if (abs(Difference) < AveragePTS) - { - return; - } - } - } - */ } diff --git a/src/imgui_helper_internal.cpp b/src/imgui_helper_internal.cpp index 3267dcc..184930e 100644 --- a/src/imgui_helper_internal.cpp +++ b/src/imgui_helper_internal.cpp @@ -1,12 +1,42 @@ #include "imgui_internal_widgets.h" - #include "imgui.h" #ifndef IMGUI_DEFINE_MATH_OPERATORS #define IMGUI_DEFINE_MATH_OPERATORS #endif #include "imgui_internal.h" + +// NOTE(fox): This API will change in the future! +void ImGui::MyWindowSetup(ImGuiID id) +{ + ImGuiViewport *Viewport = GetMainViewport(); + ImVec2 WindowMin = Viewport->WorkPos; + ImVec2 WindowSize = Viewport->WorkSize; + + DockBuilderRemoveNode(id); + DockBuilderAddNode(id, ImGuiDockNodeFlags_PassthruCentralNode | ImGuiDockNodeFlags_AutoHideTabBar); + DockBuilderSetNodeSize(id, WindowSize); + DockBuilderSetNodePos(id, WindowMin); + + ImGuiID DockTop = ImGui::DockBuilderSplitNode(id, ImGuiDir_Down, 1.f, nullptr, &id); + ImGuiID DockBottom = ImGui::DockBuilderSplitNode(DockTop, ImGuiDir_Down, 0.4f, nullptr, &DockTop); + ImGuiID DockLeft = ImGui::DockBuilderSplitNode(DockTop, ImGuiDir_Left, 0.15f, nullptr, &DockTop); + ImGuiID DockRight = ImGui::DockBuilderSplitNode(DockTop, ImGuiDir_Right, 0.2f, nullptr, &DockTop); + ImGuiID DockRightBottom = ImGui::DockBuilderSplitNode(DockRight, ImGuiDir_Down, 0.2f, nullptr, &DockRight); + ImGuiID DockRightTop = ImGui::DockBuilderSplitNode(DockRight, ImGuiDir_Up, 0.6f, nullptr, &DockRight); + + ImGui::DockBuilderDockWindow("Menu", id); + ImGui::DockBuilderDockWindow("Viewport", DockTop); + ImGui::DockBuilderDockWindow("Timeline", DockBottom); + ImGui::DockBuilderDockWindow("Properties###Properties", DockLeft); + ImGui::DockBuilderDockWindow("Colors", DockRightTop); + ImGui::DockBuilderDockWindow("Files", DockRight); + ImGui::DockBuilderDockWindow("Effects list", DockRightBottom); + + ImGui::DockBuilderFinish(id); +} + // A modded version of ScalarSlider allowing for the minimum and maximum parts // of the slider to be draggable by two other buttons. p_mid is from range -1 // to 1, and s_min and max are from 0-1. diff --git a/src/imgui_ui.cpp b/src/imgui_ui.cpp index 5247716..77a6712 100644 --- a/src/imgui_ui.cpp +++ b/src/imgui_ui.cpp @@ -618,6 +618,7 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, bool open = true; ImGui::Begin("Viewport", &open, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse); + if (ImGui::IsWindowHovered(ImGuiFocusedFlags_ChildWindows)) { State->FocusedWindow = focus_viewport; } @@ -628,6 +629,11 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, ImVec2 ViewportScale = ImGui::GetContentRegionAvail(); ImVec2 ViewportMax = ImVec2(ViewportMin.x + ViewportScale.x, ViewportMin.y + ViewportScale.y); + if (ViewportScale.x < 50 || ViewportScale.y < 50) { + ImGui::End(); + return; + } + if (State->Initializing) { UI->CompZoom = ImVec2(MainComp->Width, MainComp->Height); UI->CompPos = ImVec2(ViewportMin.x + ((ViewportMax.x - ViewportMin.x)/2 - UI->CompZoom.x/2), @@ -952,6 +958,7 @@ ImGui_Popups(project_data *File, project_state *State, ui *UI, memory *Memory, I case popup_keybinds: { ImGui::OpenPopup("Keybinds"); + ImGui::SetNextWindowSize(ImVec2(700, 700)); ImGui::SetKeyboardFocusHere(); } break; default: diff --git a/src/imgui_ui_debug.cpp b/src/imgui_ui_debug.cpp index f79fb88..8c63ff3 100644 --- a/src/imgui_ui_debug.cpp +++ b/src/imgui_ui_debug.cpp @@ -1,7 +1,7 @@ static void ImGui_DebugMemoryViewer(memory *Memory, project_state *State) { - ImGui::Begin("Memory viewer"); + ImGui::Begin("debug_memory"); ImVec2 ViewportMin = ImGui::GetCursorScreenPos(); ImVec2 ViewportScale = ImGui::GetContentRegionAvail(); diff --git a/src/imgui_ui_properties.cpp b/src/imgui_ui_properties.cpp index 5fda218..c6b710c 100644 --- a/src/imgui_ui_properties.cpp +++ b/src/imgui_ui_properties.cpp @@ -301,7 +301,7 @@ ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory * ImGui::PushID(Property); if ((h - 1) < AmountOf(Layer->Property) && c == 0) { if (ImGui::Button("K")) { - Property_AddKeyframe(Memory, F_Layers, Property, State->Frame_Current, ArrayLocation); + Property_AddKeyframe(Memory, F_Layers, Property, State->Frame_Current - Layer->Frame_Offset, ArrayLocation); } ImGui::SameLine(); #if DEBUG @@ -358,14 +358,14 @@ ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory * if (EffectHeader->DisplayType == effect_display_type_standard) { if (ChannelHeader.DisplayType == property_display_type_standard) { if (ImGui::Button("K")) { - Property_AddKeyframe(Memory, F_Properties, Property, State->Frame_Current, ArrayLocation); + Property_AddKeyframe(Memory, F_Properties, Property, State->Frame_Current - Layer->Frame_Offset, ArrayLocation); } ImGui::SameLine(); ImGui::DragScalar(Name, ImGuiDataType_Float, &Property->CurrentValue, Property->ScrubVal, &Property->MinVal, &Property->MaxVal, "%f"); ImGui_Properties_Slider(State, Memory, Property, io, WindowMinAbs, WindowMaxAbs, F_Properties); } else if (ChannelHeader.DisplayType == property_display_type_color) { if (ImGui::Button("K")) { - Property_AddKeyframe(Memory, F_Properties, Property, State->Frame_Current, ArrayLocation); + Property_AddKeyframe(Memory, F_Properties, Property, State->Frame_Current - Layer->Frame_Offset, ArrayLocation); } ImGui::SameLine(); ImGui::DragScalar(Name, ImGuiDataType_Float, &Property->CurrentValue, Property->ScrubVal, &Property->MinVal, &Property->MaxVal, "%f"); diff --git a/src/imgui_ui_timeline.cpp b/src/imgui_ui_timeline.cpp index 42bb788..92a08f6 100644 --- a/src/imgui_ui_timeline.cpp +++ b/src/imgui_ui_timeline.cpp @@ -143,7 +143,7 @@ ImGui_Timeline_GraphInfo(project_data *File, project_state *State, memory *Memor static void ImGui_Timeline_DrawKeySheet(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io, ImDrawList *draw_list, property_channel *Property, uint16 *ArrayLocation, - ImVec2 Increment, ImVec2 TimelineAbsolutePos, ImVec2 GraphPos, ImVec2 TimelineMoveSize, ImVec2 TimelineZoomSize, + ImVec2 Increment, ImVec2 TimelineAbsolutePos, ImVec2 GraphPos, int Frame_Offset, ImVec2 TimelineMoveSize, ImVec2 TimelineZoomSize, ImVec2 TimelineSize, ImVec2 TimelineSizeWithBorder, real32 LayerIncrement, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, sorted_property_array *SortedPropertyStart, uint16 *SortedKeyframeArray) { @@ -156,7 +156,7 @@ ImGui_Timeline_DrawKeySheet(project_data *File, project_state *State, memory *Me v2 PointPos[3]; Bezier_Interact_Evaluate(State, PointAddress, PointPos); - real32 LocalPos_Ratio_X = PointPos[0].x * Increment.x; + real32 LocalPos_Ratio_X = (PointPos[0].x + Frame_Offset) * Increment.x; real32 Keyframe_ScreenPos_X = GraphPos.x + TimelineMoveSize.x + LocalPos_Ratio_X * TimelineZoomSize.x; ImVec2 Keyframe_ScreenPos(Keyframe_ScreenPos_X, GraphPos.y); @@ -241,7 +241,7 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor if (!Layer->IsSelected) continue; - int32 Frame_Start = Layer->Frame_Start; + int32 Frame_Offset = Layer->Frame_Offset; ImGui::PushID(i); @@ -320,6 +320,7 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor v2 PointPos[3]; Bezier_Interact_Evaluate(State, PointAddress[Idx], PointPos, GraphZoomHeight, Y_Increment); + PointPos[0].x += Frame_Offset; ImVec2 Keyframe_LocalPos[3] = { V2(PointPos[0]), V2(PointPos[0] + PointPos[1]), V2(PointPos[0] + PointPos[2]) }; @@ -430,12 +431,13 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem int32 Frame_Start = Layer->Frame_Start; int32 Frame_End = Layer->Frame_End; + int32 Frame_Offset = Layer->Frame_Offset; real32 Vertical_Offset = SortEntry.SortedOffset + SortEntry.DisplayOffset; if (Layer->IsSelected) - Interact_Evaluate_Layer(Memory, State, Index_Physical, SortedCompStart, SortedLayerStart, &Frame_Start, &Frame_End); + Interact_Evaluate_Layer(Memory, State, Index_Physical, SortedCompStart, SortedLayerStart, &Frame_Start, &Frame_End, &Frame_Offset); - ImVec2 Layer_LocalPos = ImVec2(Frame_Start, Vertical_Offset); + ImVec2 Layer_LocalPos = ImVec2(Frame_Start + Frame_Offset, Vertical_Offset); ImVec2 Layer_LocalSize = ImVec2(Frame_End - Frame_Start, Layer->Vertical_Height); ImVec2 Layer_LocalPos_Ratio = (Layer_LocalPos * Increment); @@ -537,7 +539,7 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem // NOTE(fox): Some data on the tree could be saved here. History_Action_Swap(Memory, F_File, sizeof(Layer->Frame_Start), &Layer->Frame_Start); History_Action_Swap(Memory, F_File, sizeof(Layer->Frame_End), &Layer->Frame_End); - Interact_Evaluate_Layer(Memory, State, Index_Physical, SortedCompStart, SortedLayerStart, &Layer->Frame_Start, &Layer->Frame_End); + Interact_Evaluate_Layer(Memory, State, Index_Physical, SortedCompStart, SortedLayerStart, &Layer->Frame_Start, &Layer->Frame_End, &Layer->Frame_Offset); } } History_Entry_End(Memory); @@ -678,9 +680,8 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem History_Action_Swap(Memory, F_File, sizeof(Layer->Vertical_Offset), &Layer->Vertical_Offset); Layer->Vertical_Offset = SortEntry.SortedOffset; if (Layer->IsSelected) { - History_Action_Swap(Memory, F_File, sizeof(Layer->Frame_Start), &Layer->Frame_Start); - History_Action_Swap(Memory, F_File, sizeof(Layer->Frame_End), &Layer->Frame_End); - Interact_Evaluate_Layer(Memory, State, Index_Physical, SortedCompStart, SortedLayerStart, &Layer->Frame_Start, &Layer->Frame_End); + History_Action_Swap(Memory, F_File, sizeof(Layer->Frame_Offset), &Layer->Frame_Offset); + Interact_Evaluate_Layer(Memory, State, Index_Physical, SortedCompStart, SortedLayerStart, &Layer->Frame_Start, &Layer->Frame_End, &Layer->Frame_Offset); } } State->Interact_Active = interact_type_none; @@ -700,56 +701,59 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem while (Layer_LoopChannels(State, Memory, &InfoLocation, &ArrayLocation, Layer, &Property, &Effect, &h, &c, &p)) { if (Property->IsToggled) { - ImVec2 GraphMinPos = ImVec2(TimelineAbsolutePos.x, Layer_ScreenPos_Min.y + Layer_ScreenSize.y + (Layer_ScreenSize.y * Channel)); + ImVec2 GraphMinPos = ImVec2(TimelineAbsolutePos.x, + Layer_ScreenPos_Min.y + Layer_ScreenSize.y + (Layer_ScreenSize.y * Channel)); ImVec2 GraphPos = GraphMinPos + ImVec2(0, Layer_ScreenSize.y / 2); ImVec2 GraphMinBounds = GraphMinPos; ImVec2 GraphMaxBounds = GraphMinBounds + ImVec2(TimelineSizeWithBorder.x, Layer_ScreenSize.y); uint32 col = (Channel % 2) ? IM_COL32(50, 50, 50, 255) : IM_COL32(70, 70, 70, 255); draw_list->AddRectFilled(GraphMinBounds, GraphMaxBounds, col); ImGui_Timeline_DrawKeySheet(File, State, Memory, UI, io, draw_list, Property, ArrayLocation, - Increment, TimelineAbsolutePos, GraphPos, TimelineMoveSize, TimelineZoomSize, + Increment, TimelineAbsolutePos, GraphPos, Frame_Offset, TimelineMoveSize, TimelineZoomSize, TimelineSize, TimelineSizeWithBorder, LayerIncrement, SortedCompArray, SortedLayerArray, SortedPropertyStart, SortedKeyframeArray); Channel++; } } - } - // + // - // Precomp recursion + // Precomp recursion - if (Layer->IsPrecomp && Layer->Precomp_Toggled) { + if (Layer->IsPrecomp && Layer->Precomp_Toggled) { - sorted_layer_array *Precomp_SortedLayerStart = Sorted_GetLayerStart(SortedLayerArray, SortedCompArray, Layer->Block_Source_Index); - sorted_comp_array Precomp_SortedCompStart = SortedCompArray[Layer->Block_Source_Index]; + sorted_layer_array *Precomp_SortedLayerStart = Sorted_GetLayerStart(SortedLayerArray, SortedCompArray, Layer->Block_Source_Index); + sorted_comp_array Precomp_SortedCompStart = SortedCompArray[Layer->Block_Source_Index]; - block_layer *Layer_Top = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Precomp_SortedLayerStart[Precomp_SortedCompStart.LayerCount - 1].Block_Layer_Index); - real32 SmallestY = Layer_Top->Vertical_Offset; - real32 PrecompHeight = Precomp_SortedCompStart.DisplaySize; + block_layer *Layer_Top = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Precomp_SortedLayerStart[Precomp_SortedCompStart.LayerCount - 1].Block_Layer_Index); + sorted_layer_array TopLayerEntry = Precomp_SortedLayerStart[Precomp_SortedCompStart.LayerCount - 1]; + real32 SmallestY = TopLayerEntry.SortedOffset + TopLayerEntry.DisplayOffset; + real32 PrecompHeight = Precomp_SortedCompStart.DisplaySize; - ImVec2 MinClipPos = ImVec2(Layer_ScreenPos_Min.x, Layer_ScreenPos_Max.y); - ImVec2 MaxClipPos = ImVec2(Layer_ScreenPos_Max.x, MinClipPos.y + (PrecompHeight * Increment.y * TimelineZoomSize.y)); - draw_list->AddRectFilled(MinClipPos, MaxClipPos, ImColor(0.2f, 0.2f, 0.2f, 1.0f)); + ImVec2 MinClipPos = ImVec2(Layer_ScreenPos_Min.x, Layer_ScreenPos_Max.y + (Channel * Increment.y * TimelineZoomSize.y)); + ImVec2 MaxClipPos = ImVec2(Layer_ScreenPos_Max.x, MinClipPos.y + (PrecompHeight * Increment.y * TimelineZoomSize.y)); + draw_list->AddRectFilled(MinClipPos, MaxClipPos, ImColor(0.2f, 0.2f, 0.2f, 1.0f)); - ImVec2 Layer_LocalPos_Screen = Layer_LocalPos_Ratio * TimelineZoomSize; - ImVec2 NestedTimelineAbsolutePos = TimelineAbsolutePos + Layer_LocalPos_Screen - ImVec2(0, SmallestY * Increment.y * TimelineZoomSize.y) + ImVec2(0, Layer_ScreenSize.y * 1.5); + ImVec2 Layer_LocalPos_Screen = Layer_LocalPos_Ratio * TimelineZoomSize; + ImVec2 NestedTimelineAbsolutePos = TimelineAbsolutePos + Layer_LocalPos_Screen - ImVec2(0, (SmallestY - Channel) * Increment.y * TimelineZoomSize.y) + ImVec2(0, Layer_ScreenSize.y * 1.5); - ImGui::PushClipRect(MinClipPos, MaxClipPos, true); - draw_list->PushClipRect(MinClipPos, MaxClipPos, true); - uint32 RecursionsCount = Recursions+1; - RecursionIdx[RecursionsCount] = Index_Physical; - ImGui_Timeline_DrawPrecomp(File, State, Memory, UI, io, draw_list, RecursionIdx, RecursionsCount, - Increment, NestedTimelineAbsolutePos, TimelineMoveSize, TimelineZoomSize, - TimelineSize, TimelineSizeWithBorder, LayerIncrement, - SortedCompArray, SortedLayerArray, SortedPropertyStart, SortedKeyframeArray); - draw_list->PopClipRect(); - ImGui::PopClipRect(); + ImGui::PushClipRect(MinClipPos, MaxClipPos, true); + draw_list->PushClipRect(MinClipPos, MaxClipPos, true); + uint32 RecursionsCount = Recursions+1; + RecursionIdx[RecursionsCount] = Index_Physical; + ImGui_Timeline_DrawPrecomp(File, State, Memory, UI, io, draw_list, RecursionIdx, RecursionsCount, + Increment, NestedTimelineAbsolutePos, TimelineMoveSize, TimelineZoomSize, + TimelineSize, TimelineSizeWithBorder, LayerIncrement, + SortedCompArray, SortedLayerArray, SortedPropertyStart, SortedKeyframeArray); + draw_list->PopClipRect(); + ImGui::PopClipRect(); - } + } - // + // + + } ImGui::PopID(); } diff --git a/src/include/imgui_internal_widgets.h b/src/include/imgui_internal_widgets.h index 52fdc74..863e934 100644 --- a/src/include/imgui_internal_widgets.h +++ b/src/include/imgui_internal_widgets.h @@ -6,6 +6,7 @@ // 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 void MyWindowSetup(ImGuiID id); 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); diff --git a/src/include/main.h b/src/include/main.h index af92e31..fd295cf 100644 --- a/src/include/main.h +++ b/src/include/main.h @@ -325,7 +325,10 @@ struct project_state bool32 UpdateKeyframes = 0; bool32 UpdateFrame = 1; // only refreshes frame; set UpdateKeyframes to update animation bool32 DebugDisableCache = 1; + + // bad uint32 CachedFrameCount; + int32 LastCachedFrame = -10000; uint64 HotFramePerf = 0; @@ -562,8 +565,10 @@ struct block_layer { bool32 IsPrecomp; bool32 Precomp_Toggled; - uint16 Block_Source_Index; // also used for precomp + // NOTE(fox): References a precomp index if IsPrecomp is true, not a source index. + uint16 Block_Source_Index; uint16 Block_String_Index; + // References the precomp that the layer belongs to. uint16 Block_Composition_Index; uint16 Block_Mask_Index[MAX_MASKS]; @@ -594,8 +599,13 @@ struct block_layer { bool32 IsVisible; bool32 IsAdjustment; + // NOTE(fox): I use these in some places without calling + // Interact_Evaluate_Layer(), because I'm assuming it's impossible for + // layer dragging to happen in those contexts. Check for this if weird bugs appear. int32 Frame_Start; int32 Frame_End; + // This is what changes when the layer is dragged. It also marks the starting frame for video footage. + int32 Frame_Offset; real32 Vertical_Offset; real32 Vertical_Height = 1; diff --git a/src/main.cpp b/src/main.cpp index 1b13405..88bc3ef 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -141,6 +141,11 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, sorted_ ImGui::NewFrame(); + ImGuiID DockID = ImGui::DockSpaceOverViewport(ImGui::GetMainViewport(), ImGuiDockNodeFlags_AutoHideTabBar); + if (State->FirstFrame) { + ImGui::MyWindowSetup(DockID); + } + if (State->Warp_WantSetPos) { ImGui_WarpMouseFinish(State, io.MousePos); io.MouseDelta = {}; @@ -150,7 +155,12 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, sorted_ if (!io.WantCaptureKeyboard) ImGui_ProcessInputs(File, State, UI, Memory, io, Sorted); - ImGui::DockSpaceOverViewport(); + // The windows don't seem to draw properly on the frame after startup, so + // we need to delay a bit. + if (State->FirstFrame) { + ImGui::EndFrame(); + return; + } #if DEBUG if (Debug.ToggleWindow) { @@ -163,8 +173,8 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, sorted_ ImGui_Viewport(File, State, UI, Memory, io, textureID, Sorted.CompArray, Sorted.LayerArray, Sorted.PropertyArray); ImGui_Timeline(File, State, Memory, UI, io, Sorted.CompArray, Sorted.LayerArray, Sorted.PropertyStart, Sorted.PropertyArray); - ImGui_File(File, State, Memory, io, Sorted.CompArray, Sorted.LayerArray); ImGui_PropertiesPanel(File, State, UI, Memory, io, Sorted.CompArray, Sorted.LayerArray, Sorted.PropertyStart, Sorted.PropertyArray); + ImGui_File(File, State, Memory, io, Sorted.CompArray, Sorted.LayerArray); ImGui_ColorPanel(File, State, UI, Memory, io); ImGui_EffectsPanel(File, State, Memory, UI, io); #if STABLE @@ -295,12 +305,15 @@ Render_Comp(project_data *File, project_state *State, memory *Memory, sorted_fil int32 Frame_Start = Layer->Frame_Start; int32 Frame_End = Layer->Frame_End; + int32 Frame_Offset = Layer->Frame_Offset; if (Layer->IsSelected) - Interact_Evaluate_Layer(Memory, State, Index_Physical, *SortedCompStart, SortedLayerStart, &Frame_Start, &Frame_End); - int FrameToSeek = State->Frame_Current - Frame_Start; + Interact_Evaluate_Layer(Memory, State, Index_Physical, *SortedCompStart, SortedLayerStart, &Frame_Start, &Frame_End, &Frame_Offset); + int32 Frame_Start_Abs = Frame_Start + Frame_Offset; + int32 Frame_End_Abs = Frame_End + Frame_Offset; + int FrameToSeek = State->Frame_Current - Frame_Start_Abs; - if (Frame_Start <= Frame_Current && - Frame_End > Frame_Current && Layer->IsVisible) + if (Frame_Start_Abs <= Frame_Current && + Frame_End_Abs > Frame_Current && Layer->IsVisible) { if (State->UpdateKeyframes) { sorted_property_array *SortedLayerProperties = SortedPropertyStart + SortEntry.SortedPropertyStart; @@ -324,12 +337,15 @@ Render_Comp(project_data *File, project_state *State, memory *Memory, sorted_fil int32 Frame_Start = Layer->Frame_Start; int32 Frame_End = Layer->Frame_End; + int32 Frame_Offset = Layer->Frame_Offset; if (Layer->IsSelected) - Interact_Evaluate_Layer(Memory, State, Index_Physical, *SortedCompStart, SortedLayerStart, &Frame_Start, &Frame_End); - int FrameToSeek = State->Frame_Current - Frame_Start; + Interact_Evaluate_Layer(Memory, State, Index_Physical, *SortedCompStart, SortedLayerStart, &Frame_Start, &Frame_End, &Frame_Offset); + int32 Frame_Start_Abs = Frame_Start + Frame_Offset; + int32 Frame_End_Abs = Frame_End + Frame_Offset; + int FrameToSeek = State->Frame_Current - Frame_Start_Abs; - if (Frame_Start <= Frame_Current && - Frame_End > Frame_Current && Layer->IsVisible) + if (Frame_Start_Abs <= Frame_Current && + Frame_End_Abs > Frame_Current && Layer->IsVisible) { layer_bitmap_state *BitmapState = &State->Render.Bitmap[Index_Physical]; void *BitmapAddress = NULL; @@ -438,8 +454,10 @@ Render_Comp(project_data *File, project_state *State, memory *Memory, sorted_fil Entry_Main->CycleTime = GetCPUTime() - Comp_TimeStart; Entry_Main->IsCached = true; - if (CompIndex == File->PrincipalCompIndex) + if (CompIndex == File->PrincipalCompIndex && State->LastCachedFrame != State->Frame_Current) { State->CachedFrameCount++; + State->LastCachedFrame = State->Frame_Current; + } return CompBuffer; } @@ -488,7 +506,6 @@ Render_Blit(project_data *File, project_state *State, memory *Memory, sorted_fil static void Main_Renderer(project_data *File, project_state *State, memory *Memory, sorted_file Sorted, ui *UI, SDL_Window *window, GLuint textureID, ImGuiIO io) { - State->UpdateFrame = false; block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex); @@ -506,10 +523,11 @@ Main_Renderer(project_data *File, project_state *State, memory *Memory, sorted_f // TODO(fox): garbage collect AV state! + State->UpdateFrame = false; State->UpdateKeyframes = false; - } +static int pp = -2; int main(int argc, char *argv[]) { @@ -604,7 +622,7 @@ int main(int argc, char *argv[]) { MainComp->FPS = 60; MainComp->BytesPerPixel = 4; MainComp->Frame_Count = 80; - MainComp->Frame_End = 80; + MainComp->Frame_End = 79; MainComp->Occupied = 1; MainComp->Name_String_Index = String_AddToFile(&Memory, "Main comp"); @@ -708,18 +726,12 @@ int main(int argc, char *argv[]) { ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_DockingEnable | ImGuiConfigFlags_NavEnableSetMousePos; (void)io; - // NOTE(fox): Instead of constructing the position of the windows on - // startup with Docking API calls (which is experimental and incomplete) - // I'm loading the window positions from this convenient tool. ImGui by - // default saves window position to an external .ini file, which can be - // loaded from disk or memory. + // NOTE(fox): Window construction is done in MyWindowSetup(). #if DEBUG - io.IniFilename = NULL; - ImGui::LoadIniSettingsFromMemory(ImGuiPrefs); #else io.IniFilename = NULL; - ImGui::LoadIniSettingsFromMemory(ImGuiPrefs); #endif + // ImGui::LoadIniSettingsFromMemory(ImGuiPrefs); // ImGui::SaveIniSettingsToDisk("imgui.ini"); ImGui::StyleColorsDark(); @@ -730,6 +742,11 @@ int main(int argc, char *argv[]) { ImGui_ImplSDL2_InitForOpenGL(window, gl_context); ImGui_ImplOpenGL3_Init(glsl_version); + // ImGuiPlatformIO &plat_io = ImGui::GetPlatformIO(); + // printf("Scale: %.2f * 96 dpi", plat_io.Monitors[0].DpiScale); + // io.FontGlobalScale = plat_io.Monitors[0].DpiScale; + // printf("global: %.2f", io.FontGlobalScale); + GLuint textureID; glGenTextures(1, &textureID); glBindTexture(GL_TEXTURE_2D, textureID); @@ -748,7 +765,7 @@ int main(int argc, char *argv[]) { #endif #if DEBUG -#if 1 +#if 0 sprintf(State->DummyName, "test"); File_Open(File, State, &Memory, State->DummyName); State->UpdateFrame = true; @@ -761,6 +778,7 @@ int main(int argc, char *argv[]) { #endif #endif + while (State->IsRunning) { uint64 PerfFrequency = SDL_GetPerformanceFrequency(); @@ -806,12 +824,14 @@ int main(int argc, char *argv[]) { History_Undo(&Memory); Memory_Cache_Purge(File, State, &Memory); State->UpdateFrame = true; + State->UpdateKeyframes = true; } break; case hotkey_redo: { History_Redo(&Memory); Memory_Cache_Purge(File, State, &Memory); State->UpdateFrame = true; + State->UpdateKeyframes = true; } break; default: { @@ -832,9 +852,10 @@ int main(int argc, char *argv[]) { State->UpdateKeyframes = true; } - bool32 FullyCached = (State->CachedFrameCount == (MainComp->Frame_End - MainComp->Frame_Start)); + bool32 FullyCached = (State->CachedFrameCount == (MainComp->Frame_End - MainComp->Frame_Start + 1)); if ((State->AudioLayerIndex != -1) && FullyCached) { + Assert(0); block_layer *AudioLayer = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, State->AudioLayerIndex); av_info *AV = AV_Retrieve(State, &Memory, AudioLayer->Block_Source_Index); int32 LayerPos = AudioLayer->Frame_Start; @@ -858,9 +879,10 @@ int main(int argc, char *argv[]) { int BytesToWrite = TargetAudioSize - QueuedAudioSize; printf("%i bytes in queue.\n", QueuedAudioSize); int BytePlayhead = 0; + int32 InitialFrameToSeek = State->Frame_Current - LayerPos; while (BytePlayhead < BytesToWrite) { uint8 *Data = (uint8 *)AudioData + BytePlayhead; - int SampleCount = AV_AudioTest(AV, Data, AudioBufferSize - BytePlayhead); + int SampleCount = AV_AudioTest(AV, Data, AudioBufferSize - BytePlayhead, MainComp->FPS, InitialFrameToSeek); int Size = SampleCount * BytesPerSample; BytePlayhead += Size; } @@ -884,6 +906,8 @@ int main(int argc, char *argv[]) { if (State->Interact_Active) { Memory_Cache_Purge(File, State, &Memory, State->Frame_Current); } + // Assert(pp != State->Frame_Current); + pp = State->Frame_Current; Main_Renderer(File, State, &Memory, Sorted, &File->UI, window, textureID, io); } else if (Item.Type == 1) { Assert(State->Interact_Active == interact_type_brush); diff --git a/src/memory.cpp b/src/memory.cpp index 488f6bf..ca64745 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -193,6 +193,8 @@ Memory_Cache_Purge(project_data *File, project_state *State, memory *Memory, int c++; count--; } + State->LastCachedFrame = -10000; + State->CachedFrameCount = 0; } static cache_entry * diff --git a/src/sorted.cpp b/src/sorted.cpp index 9f2e135..46b9549 100644 --- a/src/sorted.cpp +++ b/src/sorted.cpp @@ -108,10 +108,14 @@ Layer_Sort_DisplayOffset(project_state *State, memory *Memory, } } if (SortedCompStart->LayerCount > 1) { - block_layer *Layer_Top = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, SortedLayerStart[SortedCompStart->LayerCount - 1].Block_Layer_Index); - block_layer *Layer_Bottom = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, SortedLayerStart[0].Block_Layer_Index); - real32 SmallestY = Layer_Top->Vertical_Offset; - real32 LargestY = Layer_Bottom->Vertical_Offset; + sorted_layer_array LayerEntry_Top = SortedLayerStart[SortedCompStart->LayerCount - 1]; + sorted_layer_array LayerEntry_Bottom = SortedLayerStart[0]; + real32 SmallestY = LayerEntry_Top.SortedOffset; + real32 LargestY = LayerEntry_Bottom.SortedOffset; + // block_layer *Layer_Top = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, SortedLayerStart[SortedCompStart->LayerCount - 1].Block_Layer_Index); + // block_layer *Layer_Bottom = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, SortedLayerStart[0].Block_Layer_Index); + // real32 SmallestY = Layer_Top->Vertical_Offset; + // real32 LargestY = Layer_Bottom->Vertical_Offset; DisplayOffset = LargestY - SmallestY + 2 + DisplayOffset; } return DisplayOffset; -- cgit v1.2.3