summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/createcalls.cpp5
-rw-r--r--src/ffmpeg_backend.cpp42
-rw-r--r--src/imgui_helper_internal.cpp32
-rw-r--r--src/imgui_ui.cpp7
-rw-r--r--src/imgui_ui_debug.cpp2
-rw-r--r--src/imgui_ui_properties.cpp6
-rw-r--r--src/imgui_ui_timeline.cpp78
-rw-r--r--src/include/imgui_internal_widgets.h1
-rw-r--r--src/include/main.h12
-rw-r--r--src/main.cpp74
-rw-r--r--src/memory.cpp2
-rw-r--r--src/sorted.cpp12
12 files changed, 162 insertions, 111 deletions
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;