summaryrefslogtreecommitdiff
path: root/createcalls.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'createcalls.cpp')
-rw-r--r--createcalls.cpp160
1 files changed, 137 insertions, 23 deletions
diff --git a/createcalls.cpp b/createcalls.cpp
index e88e39f..4c72c4e 100644
--- a/createcalls.cpp
+++ b/createcalls.cpp
@@ -38,6 +38,22 @@ Source_Delete(project_data *File, memory *Memory, uint32 Index)
File->Source_Count--;
}
+// These thumbnail textures aren't needed for anything else, so I'm just gonna
+// count on GL to retain them in GPU memory.
+static void
+Source_DumpThumbnail(memory *Memory, block_source *Source, uint32 T_Width, uint32 T_Height)
+{
+ Assert(Source->Type == source_type_principal_temp);
+ void *BitmapAddress = Memory_Block_AddressAtIndex(Memory, F_PrincipalBitmaps, Source->Bitmap_Index);
+ uint32 Size = T_Height*T_Width*4;
+ uint8 *Output = (uint8 *)Memory_PushScratch(Memory, Size);
+ stbir_resize_uint8((uint8 *)BitmapAddress, Source->Width, Source->Height, 0, Output, T_Height, T_Width, 0, 4);
+
+ GL_GenAndBindTexture(&Source->ThumbnailTex, T_Height, T_Width, 4, Output);
+
+ Memory_PopScratch(Memory, Size);
+}
+
static int16
Source_Generate(project_data *File, project_state *State, memory *Memory, void *TempString)
{
@@ -67,10 +83,10 @@ Source_Generate(project_data *File, project_state *State, memory *Memory, void *
}
static bezier_point *
-Bezier_LookupAddress(memory *Memory, property_channel *Property, uint16 Index)
+Bezier_LookupAddress(memory *Memory, property_channel *Property, uint16 Index, bool32 AssertExists)
{
Assert(Index < MAX_KEYFRAMES_PER_BLOCK);
- block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, Property->Block_Bezier_Index[0]);
+ block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, Property->Block_Bezier_Index[0], AssertExists);
return &Bezier->Point[Index];
}
@@ -100,7 +116,7 @@ Bezier_Add(memory *Memory, property_channel *Property, bezier_point PointData)
{
if (!Property->Block_Bezier_Count) {
Property->Block_Bezier_Index[0] = Memory_Block_AllocateNew(Memory, F_Bezier);
- block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, Property->Block_Bezier_Index[0]);
+ block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, Property->Block_Bezier_Index[0], 0);
Bezier->Occupied = true;
// NOTE(fox): Effects will change this!
History_Action_Swap(Memory, F_Layers, sizeof(Property->Block_Bezier_Count), &Property->Block_Bezier_Count);
@@ -108,7 +124,7 @@ Bezier_Add(memory *Memory, property_channel *Property, bezier_point PointData)
}
int k = 0;
for (;;) {
- bezier_point *Point = Bezier_LookupAddress(Memory, Property, k);
+ bezier_point *Point = Bezier_LookupAddress(Memory, Property, k, 0);
if (!Point->Occupied) {
History_Action_Swap(Memory, F_Bezier, sizeof(*Point), Point);
*Point = PointData;
@@ -182,6 +198,18 @@ Layer_Interact_Evaluate(memory *Memory, project_state *State, uint16 Layer_Index
}
static void
+Layer_ToggleChannel(project_data *File, memory *Memory, int32 a)
+{
+ int h = 0, c = 0, i = 0;
+ while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i))
+ {
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i);
+ if (Layer->IsSelected)
+ Layer->Property[a].IsToggled ^= 1;
+ }
+}
+
+static void
Layer_Select(memory *Memory, project_state *State, int32 i)
{
block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i);
@@ -208,23 +236,47 @@ void Source_DeselectAll(project_data *File, memory *Memory)
}
}
-void Clipboard_Paste(project_data *File, project_state *State, memory *Memory, sorted_layer *SortedLayerArray)
+// NOTE(fox): This won't work with precomps!
+
+void Clipboard_Paste(project_data *File, project_state *State, memory *Memory, sorted_comp_info *SortedCompInfo, sorted_layer *SortedLayerInfo)
{
clipboard_contents *Contents = (clipboard_contents *)State->ClipboardBuffer;
+ if (Contents->Type == selection_none)
+ return;
uint64 ClipboardPos = sizeof(clipboard_contents);
ClipboardPos = sizeof(clipboard_contents);
- int h = 0, c = 0, i = 0;
- block_layer *Layer;
+ int i = SortedCompInfo->LayerCount - 1;
+ block_layer *Layer = NULL;
clipboard_channel *Channel;
int b = 0;
- while (b < Contents->ChannelCount) {
+ int LayerCount = 0;
+
+ int NumberOfLayersFromClipboard = 1;
+ int LastOffset = 0;
+ for (int a = 0; a < Contents->ChannelCount; a++) {
+ Channel = &Contents->Channel[a];
+ if (a != 0) {
+ if (Channel->LayerOffset != LastOffset)
+ NumberOfLayersFromClipboard++;
+ }
+ LastOffset = Channel->LayerOffset;
+ }
+
+ for (;;) {
Channel = &Contents->Channel[b];
- while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i))
+ while (i >= 0)
{
- Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i);
- if (Layer->IsSelected)
+ sorted_layer SortEntry = SortedLayerInfo[i];
+ uint32 Index_Physical = SortEntry.Block_Layer_Index;
+ block_layer *TestLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i);
+ if (TestLayer->IsSelected) {
+ Layer = TestLayer;
break;
+ }
+ i--;
}
+ if (Layer == NULL)
+ break;
// NOTE(fox): This loop assumes all layers and the clipboard have
// channels laid out in the same way!
for (int h = 0; h < AmountOf(Layer->Property); h++) {
@@ -232,6 +284,7 @@ void Clipboard_Paste(project_data *File, project_state *State, memory *Memory, s
if (Property->Name == Channel->Name) {
for (int p = 0; p < Channel->KeyframeCount; p++) {
bezier_point PointData = *(bezier_point *)((uint8 *)State->ClipboardBuffer + ClipboardPos);
+ PointData.Pos[0].x += State->Frame_Current;
Bezier_Add(Memory, Property, PointData);
ClipboardPos += sizeof(bezier_point);
}
@@ -239,22 +292,26 @@ void Clipboard_Paste(project_data *File, project_state *State, memory *Memory, s
Channel = &Contents->Channel[b];
}
}
+ Layer = NULL;
+ if (b < Contents->ChannelCount) {
+ if (NumberOfLayersFromClipboard != 1)
+ break;
+ else
+ b = 0;
+ }
}
}
-void Clipboard_Store(project_data *File, project_state *State, memory *Memory, sorted_property_info *SortedPropertyInfo, uint16 *SortedPropertyArray)
+void Clipboard_Store(project_data *File, project_state *State, memory *Memory, sorted_comp_info *SortedCompInfo, sorted_layer *SortedLayerInfo, sorted_property_info *SortedPropertyInfo, uint16 *SortedPropertyArray)
{
- // TODO(fox): Multi-precomp support!
int LocalOffset = 0;
clipboard_contents *Contents = (clipboard_contents *)State->ClipboardBuffer;
*Contents = {};
uint64 ClipboardPos = sizeof(clipboard_contents);
- // for (int i = SortedCompInfo.LayerCount - 1; i >= 0; i--)
- Assert(0);
- for (int i = 10; i >= 0; i--)
+ for (int i = SortedCompInfo->LayerCount - 1; i >= 0; i--)
{
- sorted_layer SortEntry = {}; // SortedLayerInfo[i];
+ sorted_layer SortEntry = SortedLayerInfo[i];
uint32 Index_Physical = SortEntry.Block_Layer_Index;
block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical);
for (int h = 0; h < AmountOf(Layer->Property); h++) {
@@ -263,10 +320,18 @@ void Clipboard_Store(project_data *File, project_state *State, memory *Memory, s
sorted_property_info *InfoLocation = SortedPropertyInfo + (i * 7) + h;
uint16 *ArrayLocation = SortedPropertyArray + (i * 7 * MAX_KEYFRAMES_PER_BLOCK) + (h * MAX_KEYFRAMES_PER_BLOCK);
clipboard_channel *Channel = &Contents->Channel[Contents->ChannelCount];
+ bezier_point *FirstPoint = NULL;
+ int TimeOffset = 0;
for (int p = 0; p < Property->Keyframe_Count; p++) {
bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, ArrayLocation[p]);
if (PointAddress->IsSelected) {
- Memory_Copy((uint8 *)State->ClipboardBuffer + ClipboardPos, (uint8 *)PointAddress, sizeof(bezier_point));
+ if (!FirstPoint) {
+ FirstPoint = PointAddress;
+ TimeOffset = FirstPoint->Pos[0].x;
+ }
+ bezier_point PointToCopy = *PointAddress;
+ PointToCopy.Pos[0].x -= TimeOffset;
+ Memory_Copy((uint8 *)State->ClipboardBuffer + ClipboardPos, (uint8 *)&PointToCopy, sizeof(bezier_point));
ClipboardPos += sizeof(bezier_point);
Channel->KeyframeCount++;
}
@@ -486,6 +551,35 @@ void Layer_Evaluate_Display(block_layer *Layer, sorted_layer *LayerArrayStart, s
*/
}
+void TempSource_SortAll(project_data *File, project_state *State, memory *Memory, uint16 *SourceArrayStart, uint16 *TempSourceCount)
+{
+ int count = 0;
+ int h = 0, c = 0, i = 0;
+ while (Block_Loop(Memory, F_Sources, File->Source_Count, &h, &c, &i)) {
+ block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, i);
+ if (Source->Type == source_type_principal_temp) {
+ uint32 Playhead = 0;
+ while (Playhead < count) {
+ block_source *TestSource = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, SourceArrayStart[Playhead]);
+ Assert(TestSource->Type == source_type_principal_temp);
+ if (TestSource->RelativeTimestamp > Source->RelativeTimestamp) {
+ break;
+ } else {
+ Playhead++;
+ }
+ }
+ if (Playhead != count) {
+ uint8 *Address_Start = (uint8 *)(SourceArrayStart + Playhead);
+ uint8 *Address_End = (uint8 *)(SourceArrayStart + count) - 1;
+ Arbitrary_ShiftData(Address_Start, Address_End, sizeof(uint16), 1);
+ }
+ SourceArrayStart[Playhead] = i;
+ count++;
+ }
+ }
+ *TempSourceCount = count;
+}
+
// The first loop is for counting how many layers are in each precomp, the
// second is for sorting the layers by offset, and the third is for applying
// interactivity if the user is moving any layers.
@@ -591,12 +685,20 @@ sorted_file File_Sort_Push(project_data *File, project_state *State, memory *Mem
Sorted.PropertyInfo = (sorted_property_info *)Property_SortedArray;
Sorted.PropertyArray = (uint16 *)((uint8 *)Property_SortedArray + PropertyInfoSize);
+ uint64 SourceArraySize = sizeof(uint16) * File->Source_Count;
+ Sorted.Source_SortSize = SourceArraySize;
+ void *Source_SortedArray = Memory_PushScratch(Memory, Sorted.Source_SortSize);
+ Arbitrary_Zero((uint8 *)Source_SortedArray, Sorted.Source_SortSize);
+ Sorted.SourceArray = (uint16 *)Source_SortedArray;
+
+ TempSource_SortAll(File, State, Memory, Sorted.SourceArray, &Sorted.TempSourceCount);
Layer_SortAll(File, State, Memory, Sorted.LayerArray, Sorted.CompArray, Sorted.PropertyInfo, Sorted.PropertyArray, File->Layer_Count, File->Comp_Count);
return Sorted;
}
-void File_Sort_Pop(memory *Memory, uint64 Layer_SortSize, uint64 Property_SortSize)
+void File_Sort_Pop(memory *Memory, uint64 Layer_SortSize, uint64 Property_SortSize, uint64 Source_SortSize)
{
+ Memory_PopScratch(Memory, Source_SortSize);
Memory_PopScratch(Memory, Property_SortSize);
Memory_PopScratch(Memory, Layer_SortSize);
}
@@ -844,6 +946,7 @@ Brush_Info(brush_info *B, brush_state *Brush, block_source *Source, v2 LayerPos,
}
B->BrushBuffer = Brush->PaintBuffer;
+ B->EraseMode = Brush->EraseMode;
// ImGui's color picker works in sRGB, so we need to convert to linear.
// real32 R_Brush = (Color.r >= 0.04045) ? pow((Color.r + 0.055) / (1 + 0.055), 2.4) : Color.r / 12.92;
@@ -890,11 +993,22 @@ PaintTest(brush_info B, void *Buffer, rectangle RenderRegion)
real32 BrushAlpha = Brush_BitmapAlpha * B.A_Brush;
real32 LayerAlpha = A_Layer;
- real32 A_Blend = LayerAlpha + BrushAlpha;
+ real32 A_Blend = 0;
+ real32 R_Blend = 0;
+ real32 G_Blend = 0;
+ real32 B_Blend = 0;
- real32 R_Blend = (R_Layer * (1.0f - BrushAlpha)) + (B.R_Brush * BrushAlpha);
- real32 G_Blend = (G_Layer * (1.0f - BrushAlpha)) + (B.G_Brush * BrushAlpha);
- real32 B_Blend = (B_Layer * (1.0f - BrushAlpha)) + (B.B_Brush * BrushAlpha);
+ if (!B.EraseMode) {
+ A_Blend = LayerAlpha + BrushAlpha;
+ R_Blend = (R_Layer * (1.0f - BrushAlpha)) + (B.R_Brush * BrushAlpha);
+ G_Blend = (G_Layer * (1.0f - BrushAlpha)) + (B.G_Brush * BrushAlpha);
+ B_Blend = (B_Layer * (1.0f - BrushAlpha)) + (B.B_Brush * BrushAlpha);
+ } else {
+ A_Blend = A_Layer * (1.0f - BrushAlpha);
+ R_Blend = R_Layer;
+ G_Blend = G_Layer;
+ B_Blend = B_Layer;
+ }
/*
R_Blend = (R_Brush * (1.0f - LayerAlpha)) + (R_Blend * LayerAlpha);