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 --- createcalls.cpp | 1967 ------------------------------------------------------- 1 file changed, 1967 deletions(-) delete mode 100644 createcalls.cpp (limited to 'createcalls.cpp') diff --git a/createcalls.cpp b/createcalls.cpp deleted file mode 100644 index 4be6b45..0000000 --- a/createcalls.cpp +++ /dev/null @@ -1,1967 +0,0 @@ -static void -PostMsg(project_state *State, char *msg) -{ - State->MsgTime = 120; - State->Msg = msg; -} - -static bool32 -File_Open(project_data *File, project_state *State, memory *Memory, char *Filename) -{ - SDL_RWops *FileHandle = SDL_RWFromFile(Filename, "r+b"); - if (!FileHandle) { - return 0; - } - uint64 FileSize = SDL_RWseek(FileHandle, 0, RW_SEEK_END); - void *CompressedData = Memory_PushScratch(Memory, FileSize); - SDL_RWseek(FileHandle, 0, RW_SEEK_SET); - IO_ReadFromStream(CompressedData, FileSize, FileHandle); - SDL_RWclose(FileHandle); - Data_Decompress(Memory, CompressedData, FileSize, File, 0); - Memory_PopScratch(Memory, FileSize); - - // Temp sources aren't cleaned out on file close, so we do it here. - int h = 0, c = 0, i = 0; - int Count = File->Source_Count; - while (Block_Loop(Memory, F_Sources, Count, &h, &c, &i)) { - block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, i); - if (Source->Type == source_type_principal_temp) { - Source->Occupied = 0; - File->Source_Count--; - } - } - String_Copy(State->Filename, State->DummyName, 512); - State->Initializing = 4; - Memory->History.NumberOfEntries = 0; - Memory->History.EntryPlayhead = 0; - return 1; -} - -static bool32 -IO_Save(project_data *File, project_state *State, memory *Memory, char *Filename) -{ - SDL_RWops *TestFile = SDL_RWFromFile(Filename, "wb"); - - if (!TestFile) - return 0; - - uint8 *FileEndAddress = (uint8 *)Memory->Slot[F_PrincipalBitmaps].Address; - 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) { - uint64 Size = Source->Width * Source->Height * Source->BytesPerPixel; - void *SourceBitmapAddress = Memory_Block_AddressAtIndex(Memory, F_PrincipalBitmaps, Source->Bitmap_Index, 0); - uint8 *BitmapEnd = (uint8 *)SourceBitmapAddress + Size; - if (BitmapEnd > FileEndAddress) - FileEndAddress = BitmapEnd; - } - } - - Assert(FileEndAddress); - uint64 FileSize = FileEndAddress - (uint8 *)File; - - void *CompressedLocation = Memory_PushScratch(Memory, FileSize); - - uint64 CompressedSize = Data_Compress(Memory, File, FileSize, CompressedLocation, FileSize, Z_BEST_COMPRESSION); - - Memory_PopScratch(Memory, FileSize); - - IO_WriteToStream(CompressedLocation, CompressedSize, TestFile); - SDL_RWclose(TestFile); - - Memory->IsFileSaved = true; - - return 1; -} - -static void -File_SaveAs(project_data *File, project_state *State, memory *Memory, char *Filename) -{ - if (IO_Save(File, State, Memory, State->Filename)) { - PostMsg(State, "File saved!"); - } else { - PostMsg(State, "File save failed..."); - } -} - -static void -Playhead_Increment(int32 *Frame_Current, int32 Frame_Start, int32 Frame_End, int32 Increment) -{ - *Frame_Current += Increment; - if (*Frame_Current >= Frame_End) { - *Frame_Current = Frame_Start; - } - // if (*Frame_Current < Frame_Start) { - // } -} - -static uint16 -Source_Generate_Blank(project_data *File, project_state *State, memory *Memory, uint16 Width, uint16 Height, uint16 BytesPerPixel) -{ - Assert(File->Source_Count < MAX_SOURCES); - uint16 Index = Memory_Block_AllocateNew(Memory, F_Sources); - block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Index, 0); - History_Action_Block_Swap(Memory, F_Sources, Source); - Source->Occupied = 1; - Source->Width = Width; - Source->Height = Height; - Source->BytesPerPixel = BytesPerPixel; - Source->Type = source_type_principal; - Source->Bitmap_Index = Memory_Block_PrincipalBitmap_AllocateNew(File, State, Memory); - Source->Path_String_Index = String_AddToFile(Memory, "test"); - History_Action_Swap(Memory, F_File, sizeof(File->Source_Count), &File->Source_Count); - File->Source_Count++; - return Index; -} - -static bool32 Source_IsFileSupported(char *Path, bool32 *IsVideo) { - return stbi_info(Path, NULL, NULL, NULL); - // AV_IsFileSupported(Path, IsVideo) -} - -static void -Source_Delete(project_data *File, memory *Memory, uint32 Index) -{ - block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Index); - History_Action_Block_Swap(Memory, F_Sources, Source); - Source->Occupied = 0; - History_Action_Swap(Memory, F_File, sizeof(File->Source_Count), &File->Source_Count); - 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, 0); - 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) -{ - Assert(File->Source_Count < MAX_SOURCES); - - bool32 IsVideo = 0; - if (Source_IsFileSupported((char *)TempString, &IsVideo)) { - uint16 Index = Memory_Block_AllocateNew(Memory, F_Sources); - block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Index, 0); - History_Entry_Commit(Memory, "Add source"); - History_Action_Block_Swap(Memory, F_Sources, Source); - - Source->Occupied = 1; - Source->Path_String_Index = String_AddToFile(Memory, (char *)TempString); - Assert(!IsVideo); - Source->Type = source_type_file; - - History_Action_Swap(Memory, F_File, sizeof(File->Source_Count), &File->Source_Count); - File->Source_Count++; - History_Entry_End(Memory); - return Index; - } else { - PostMsg(State, "File not supported..."); - } - - return -1; -} - -static bezier_point * -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], AssertExists); - return &Bezier->Point[Index]; -} - -// NOTE(fox): It's not required for the Y to be set correctly in i.e. sorting. -static void -Bezier_EvaluateValue(project_state *State, bezier_point *PointAddress, v2 *Pos, real32 GraphZoomHeight = 1, real32 Y_Increment = 1) -{ - Pos[0] = PointAddress->Pos[0]; - Pos[1] = PointAddress->Pos[1]; - Pos[2] = PointAddress->Pos[2]; - if (PointAddress->IsSelected) { - if (State->Interact_Active == interact_type_keyframe_move) { - if (State->Interact_Modifier != 2) - Pos[PointAddress->IsSelected - 1].x += (int32)State->Interact_Offset[0]; - if (State->Interact_Modifier != 1) - Pos[PointAddress->IsSelected - 1].y -= (State->Interact_Offset[1] / GraphZoomHeight / Y_Increment); - } else if (State->Interact_Active == interact_type_keyframe_scale) { - Pos[1].x += State->Interact_Offset[0]; - Pos[2].x -= State->Interact_Offset[0]; - } else if (State->Interact_Active == interact_type_keyframe_rotate) { - // how do I do this?? - Assert(0); - } - } -} - -// TODO(fox): Test multiple keyframe blocks! -static void -Bezier_Add(memory *Memory, memory_table_list TableName, property_channel *Property, bezier_point PointData, uint16 *ArrayLocation) -{ - if (!Property->Block_Bezier_Count) { - Assert(Property->Keyframe_Count < MAX_KEYFRAMES_PER_BLOCK); - 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], 0); - Bezier->Occupied = true; - History_Action_Swap(Memory, TableName, sizeof(Property->Block_Bezier_Count), &Property->Block_Bezier_Count); - Property->Block_Bezier_Count++; - } - // First check to see if the point to add overlaps an existing keyframe: - if (ArrayLocation) { - for (int p = 0; p < Property->Keyframe_Count; p++) { - int k = ArrayLocation[p]; - bezier_point *Point = Bezier_LookupAddress(Memory, Property, k); - if (Point->Pos[0].x == PointData.Pos[0].x) { - History_Action_Swap(Memory, F_Bezier, sizeof(*Point), Point); - *Point = PointData; - return; - } - } - } - int k = 0; - for (;;) { - bezier_point *Point = Bezier_LookupAddress(Memory, Property, k, 0); - if (!Point->Occupied) { - History_Action_Swap(Memory, F_Bezier, sizeof(*Point), Point); - *Point = PointData; - History_Action_Swap(Memory, TableName, sizeof(Property->Keyframe_Count), &Property->Keyframe_Count); - Property->Keyframe_Count++; - return; - } - k++; - } -} - -static void -Property_AddKeyframe(memory *Memory, memory_table_list TableName, property_channel *Property, int Frame, uint16 *ArrayLocation) -{ - History_Entry_Commit(Memory, "Add keyframe"); - bezier_point Point = { 1, {(real32)Frame, Property->CurrentValue, -1, 0, 1, 0}, interpolation_type_linear, 0, {0, 0, 0}, 0 }; - Bezier_Add(Memory, TableName, Property, Point, ArrayLocation); - History_Entry_End(Memory); -} - -// static void -// Property_InitFloat(char *Name, real32 Val, real32 ScrubVal, real32 MinVal = PROPERTY_REAL_MIN, real32 MaxVal = PROPERTY_REAL_MAX, bool32 AlwaysInteger = 0) { -// { -// } - -static property_channel -Property_InitFloat(real32 Val, real32 ScrubVal, real32 MinVal = PROPERTY_REAL_MIN, real32 MaxVal = PROPERTY_REAL_MAX, bool32 AlwaysInteger = 0) { - property_channel Property = {}; - Property.CurrentValue = Val; - Property.MinVal = MinVal; - Property.MaxVal = MaxVal; - Property.AlwaysInteger = AlwaysInteger; - Property.ScrubVal = ScrubVal; - return Property; -} - -static block_composition * -Precomp_Init(project_data *File, memory *Memory) -{ - if (File->Comp_Count + 1 > MAX_COMPS) { - Assert(0); - } - block_composition *Comp = (block_composition *)Memory_Block_AllocateAddress(Memory, F_Precomps); - History_Action_Block_Swap(Memory, F_Precomps, Comp); - - *Comp = {}; - Comp->Occupied = 1; - - Comp->Name_String_Index = Memory_Block_AllocateNew(Memory, F_Strings); - block_string *String = (block_string *)Memory_Block_AddressAtIndex(Memory, F_Strings, Comp->Name_String_Index, 0); - sprintf(String->Char, "Comp %i", File->Comp_Count); - String->Occupied = 1; - - History_Action_Swap(Memory, F_File, sizeof(File->Comp_Count), &File->Comp_Count); - File->Comp_Count++; - return Comp; -} - -static layer_transforms -Layer_GetTransforms(block_layer *Layer) { - return { Layer->x.CurrentValue, Layer->y.CurrentValue, Layer->ax.CurrentValue, Layer->ay.CurrentValue, Layer->rotation.CurrentValue, Layer->scale.CurrentValue }; -} - -static void -Layer_Interact_Evaluate(memory *Memory, project_state *State, uint16 Layer_Index_Physical, sorted_comp_info SortedCompInfo, sorted_layer *SortedLayerInfo, - int32 *Frame_Start, int32 *Frame_End) -{ - if (State->Interact_Active == interact_type_layer_move) { - *Frame_Start += (int32)(State->Interact_Offset[0] + 0); - *Frame_End += (int32)(State->Interact_Offset[0] + 0); - } - if (State->Interact_Active == interact_type_layer_timeadjust) { - int Side[2] = {0}; - Assert(State->Interact_Offset[1] == 0 || State->Interact_Offset[1] == 1); - Side[(int)State->Interact_Offset[1]] = 1; - *Frame_Start += (int32)(State->Interact_Offset[0] * Side[0]); - if (*Frame_Start >= *Frame_End) - *Frame_Start = *Frame_End - 1; - *Frame_End += (int32)(State->Interact_Offset[0] * Side[1]); - if (*Frame_End <= *Frame_Start) - *Frame_End = *Frame_Start + 1; - } -} - -static uint32 -Effect_Init(project_state *State, memory *Memory, uint32 EffectEntryIndex, int EffectCount) -{ - uint16 EffectAddressIndex = Memory_Block_AllocateNew(Memory, F_Effects); - block_effect *Effect = (block_effect *)Memory_Block_AddressAtIndex(Memory, F_Effects, EffectAddressIndex, 0); - History_Action_Block_Swap(Memory, F_Effects, Effect); - *Effect = {}; - Effect->Occupied = true; - header_effect *EffectHeader = &State->Effect[EffectEntryIndex]; - String_Copy(Effect->ID, EffectHeader->ID, 8); - Effect->IsToggled = true; - Effect->Index = EffectCount; - for (int e = 0; e < EffectHeader->Property_Count; e++) { - Effect->Block_Property_Index[e] = Memory_Block_AllocateNew(Memory, F_Properties); - property_channel *Property = (property_channel *)Memory_Block_AddressAtIndex(Memory, F_Properties, Effect->Block_Property_Index[e], 0); - History_Action_Block_Swap(Memory, F_Properties, Property); - Property->Occupied = true; - header_property PropertyHeader = State->Property[EffectHeader->PropertyStartIndex + e]; - Property->Identifier = -1; - Property->CurrentValue = PropertyHeader.DefaultValue; - Property->MinVal = PropertyHeader.MinVal; - Property->MaxVal = PropertyHeader.MaxVal; - } - return EffectAddressIndex; -} - -static void -Effect_Add(project_data *File, project_state *State, memory *Memory, uint32 EffectEntryIndex) -{ - History_Entry_Commit(Memory, "Add effect"); - int h = 0, c = 0, i = 0; - int Selected = 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->Block_Effect_Index[Layer->Block_Effect_Count] = Effect_Init(State, Memory, EffectEntryIndex, Layer->Block_Effect_Count); - History_Action_Swap(Memory, F_File, sizeof(Layer->Block_Effect_Count), &Layer->Block_Effect_Count); - Layer->Block_Effect_Count++; - Selected++; - } - } - History_Entry_End(Memory); - Assert(Selected); -} - -static void -Layer_UpdateMasksEffects(project_state *State, block_layer *Layer, memory *Memory, void *EffectBitmapAddress, - int Width, int Height, int BytesPerPixel) -{ - uint64 Size = Width*Height*BytesPerPixel; - - // We need two of these: one with multisampling enabled and a - // non-multisampled one that we can blit to. - gl_effect_layer TestL = {}; - gl_effect_layer TestM = {}; - - GL_UpdateTexture(&TestL, EffectBitmapAddress, Width, Height, BytesPerPixel, 0); - GL_UpdateTexture(&TestM, EffectBitmapAddress, Width, Height, BytesPerPixel, 1); - - for (int i = 0; i < Layer->Block_Effect_Count; i++) - { - block_effect Effect = *(block_effect *)Memory_Block_AddressAtIndex(Memory, F_Effects, Layer->Block_Effect_Index[i]); - header_effect *EffectEntry = Effect_EntryFromID(State, Effect.ID); - - if (Effect.IsToggled) { - uint64 Size = (sizeof(real32) * MAX_PROPERTIES_PER_EFFECT) + (sizeof(real32) * 10); - real32 *Data; - if (EffectEntry->DisplayType == effect_display_type_curves) { - Data = (real32 *)Memory_PushScratch(Memory, Size); - uint16 SortedPointIndex[MAX_PROPERTIES_PER_EFFECT]; - v2 *SortedPointValues = (v2 *)(Data + 5); - for (int c = 0; c < 5; c++) { - *(Data + c) = Effect.ExtraData[c]; - uint32 Shift = MAX_PROPERTIES_PER_EFFECT / 5 * c; - uint16 *SortedPointIndexPlayhead = SortedPointIndex + Shift; - v2 *SortedPointValuesPlayhead = SortedPointValues + Shift; - Effect_Curves_Sort(Memory, &Effect, SortedPointIndexPlayhead, c); - for (int a = 0; a < Effect.ExtraData[c]; a++) { - *SortedPointValuesPlayhead = Effect_V2(Memory, &Effect, SortedPointIndexPlayhead[a]); - SortedPointValuesPlayhead++; - } - } - } else { - Data = (real32 *)Memory_PushScratch(Memory, Size); - for (int c = 0; c < EffectEntry->Property_Count; c++) { - property_channel *Property = (property_channel *)Memory_Block_AddressAtIndex(Memory, F_Properties, Effect.Block_Property_Index[c]); - Data[c] = Property->CurrentValue; - } - } - EffectEntry->func(Data, Width, Height, BytesPerPixel, EffectBitmapAddress, EffectEntry->GLShaderIndex); - Memory_PopScratch(Memory, Size); - } - } - /* - if (Layer->NumberOfMasks) { - for (int i = 0; i < Layer->NumberOfMasks; i++) { - file_mask_header *MaskHeader = (file_mask_header *)((uint8 *)Layer + sizeof(file_layer) + MaskOffset); - if (MaskHeader->IsClosed && MaskHeader->IsToggled) { - mask_point *Point = (mask_point *)((uint8 *)MaskHeader + sizeof(file_mask_header)); - Mask_TriangulateAndRasterize(TestM, TestL, Memory, MaskHeader, Point, Source->Width, Source->Height, Source->BytesPerPixel, EffectBitmapAddress); - } - } - Bitmap_StencilAlpha(SourceBitmapAddress, EffectBitmapAddress, Source->BytesPerPixel, Size); - } - - Layer->OutputBitmapLocation = EffectBitmapAddress; - */ - - GL_DeleteHWBuffer(&TestL); - GL_DeleteHWBuffer(&TestM); -} - -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); - Layer->IsSelected = true; - State->MostRecentlySelectedLayer = i; - State->RecentSelectionType = selection_type_layer; -} - -static void -Layer_Select_RecurseUp(memory *Memory, project_state *State, int32 i, int16 RecursionIdx[MAX_PRECOMP_RECURSIONS], uint32 Recursions) -{ - for (int a = 1; a <= Recursions; a++) { - block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, RecursionIdx[a]); - Layer->IsSelected = 2; - } -} - -void Layer_DeselectAll(project_data *File, project_state *State, memory *Memory) { - 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); - Layer->IsSelected = false; - } - State->MostRecentlySelectedLayer = -1; -} - -void Source_DeselectAll(project_data *File, memory *Memory) -{ - 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); - Source->IsSelected = 0; - } -} - -// h: index of the total amount of properties and effects -// c: index of the amount of properties in a given effect -// p: prior property's keyframe count, so we can increment the sorted keyframe array properly -static bool32 -Layer_LoopChannels(project_state *State, memory *Memory, sorted_property_info **SortedProperty, uint16 **SortedKeyframe, block_layer *Layer, - property_channel **Property, block_effect **EffectOut, int *h, int *c, int *p) -{ - uint32 Amount = AmountOf(Layer->Property) + Layer->Block_Effect_Count; - // Assert(Layer->Block_Effect_Count < 2); - while (*h < Amount) { - if (*h < AmountOf(Layer->Property) && *c == 0) { - *Property = &Layer->Property[*h]; - if (*h != 0) { - *SortedProperty += 1; - *SortedKeyframe += *p; - } - *h += 1; - *p = (**Property).Keyframe_Count; - return 1; - } else { - uint16 EffectIdx = Layer->Block_Effect_Index[*h - AmountOf(Layer->Property)]; - block_effect *Effect = (block_effect *)Memory_Block_AddressAtIndex(Memory, F_Effects, EffectIdx); - if (EffectOut) - *EffectOut = Effect; - header_effect *EffectHeader = Effect_EntryFromID(State, Effect->ID); - while (*c < EffectHeader->Property_Count) { - // header_property ChannelHeader = State->Property[EffectHeader->PropertyStartIndex + c]; - *Property = (property_channel *)Memory_Block_AddressAtIndex(Memory, F_Properties, Effect->Block_Property_Index[*c]); - *SortedProperty += 1; - *SortedKeyframe += *p; - *p = (**Property).Keyframe_Count; - *c += 1; - return 1; - } - *h += 1; - *c = 0; - } - } - Assert(*h != (Amount - 1)); - return 0; -} - -static void -Layer_ToggleAllChannels(project_state *State, memory *Memory, block_layer *Layer, - sorted_comp_info *SortedCompInfo, sorted_layer *SortedLayerInfo, - sorted_property_info *SortedPropertyInfo, uint16 *SortedPropertyArray) -{ - bool32 ToggleMode = 1; - { - sorted_property_info *InfoLocation = SortedPropertyInfo + SortedLayerInfo->SortedPropertyStart; - uint16 *ArrayLocation = SortedPropertyArray + SortedLayerInfo->SortedKeyframeStart; - int h = 0, c = 0, p = 0; - property_channel *Property = NULL; - block_effect *Effect = NULL; - while (Layer_LoopChannels(State, Memory, &InfoLocation, &ArrayLocation, Layer, &Property, &Effect, &h, &c, &p)) - { - if (Property->IsToggled) { - ToggleMode = 0; - break; - } - } - } - sorted_property_info *InfoLocation = SortedPropertyInfo + SortedLayerInfo->SortedPropertyStart; - uint16 *ArrayLocation = SortedPropertyArray + SortedLayerInfo->SortedKeyframeStart; - int h = 0, c = 0, p = 0; - property_channel *Property = NULL; - block_effect *Effect = NULL; - while (Layer_LoopChannels(State, Memory, &InfoLocation, &ArrayLocation, Layer, &Property, &Effect, &h, &c, &p)) - { - if (Property->Keyframe_Count) { - Property->IsToggled = ToggleMode; - } - } -} - -static void -Project_ToggleAllChannels(project_data *File, project_state *State, memory *Memory, - sorted_comp_info *SortedCompInfo, sorted_layer *SortedLayerInfo, - sorted_property_info *SortedPropertyInfo, uint16 *SortedPropertyArray) -{ - 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_ToggleAllChannels(State, Memory, Layer, SortedCompInfo, SortedLayerInfo, SortedPropertyInfo, SortedPropertyArray); - } - } -} - -inline sorted_property_info * -Property_GetSortedInfo(sorted_property_info *SortedPropertyInfo, int i, int h) -{ - Assert(0); - return SortedPropertyInfo + (i * 8) + h; -} -inline uint16 * -Property_GetSortedArray(uint16 *SortedPropertyArray, int i, int h) -{ - Assert(0); - return SortedPropertyArray + (i * 8 * MAX_KEYFRAMES_PER_BLOCK) + (h * MAX_KEYFRAMES_PER_BLOCK); -} - -static sorted_layer * -Layer_GetSortedArray(sorted_layer *LayerArrayStart, sorted_comp_info *SortedCompStart, uint32 TargetComp) -{ - uint32 LayerOffset = 0; int s = 0; - while (s < TargetComp) { - LayerOffset += SortedCompStart[s].LayerCount; - s++; - } - return LayerArrayStart + LayerOffset; -} - -static void -Bezier_Commit(project_data *File, project_state *State, memory *Memory, - sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray, - sorted_property_info *SortedPropertyInfo, uint16 *SortedPropertyArray) -{ - History_Entry_Commit(Memory, "Move keyframe"); - 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); - sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, Layer->Block_Composition_Index); - if ((State->TimelineMode == timeline_mode_graph) && !Layer->IsSelected) - continue; - sorted_property_info *InfoLocation = SortedPropertyInfo + SortedLayerInfo->SortedPropertyStart; - uint16 *ArrayLocation = SortedPropertyArray + SortedLayerInfo->SortedKeyframeStart; - int h = 0, c = 0, p = 0; - property_channel *Property = NULL; - block_effect *Effect = NULL; - while (Layer_LoopChannels(State, Memory, &InfoLocation, &ArrayLocation, Layer, &Property, &Effect, &h, &c, &p)) - { - if ((State->TimelineMode != timeline_mode_graph) && !Property->IsToggled) - continue; - for (int p = 0; p < Property->Keyframe_Count; p++) { - int k = ArrayLocation[p]; - bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, k); - if (PointAddress->IsSelected) { - v2 NewPos[3]; - Bezier_EvaluateValue(State, PointAddress, NewPos); - History_Action_Swap(Memory, F_Bezier, sizeof(PointAddress->Pos), &PointAddress->Pos); - PointAddress->Pos[0] = NewPos[0]; - PointAddress->Pos[1] = NewPos[1]; - PointAddress->Pos[2] = NewPos[2]; - } - } - } - } - History_Entry_End(Memory); - State->Interact_Offset[0] = 0; - State->Interact_Offset[1] = 0; - State->Interact_Offset[2] = 0; - State->Interact_Offset[3] = 0; - State->Interact_Active = interact_type_none; - State->Interact_Modifier = 0; -} - -// 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, uint16 *SortedPropertyArray) -{ - clipboard_contents *Contents = (clipboard_contents *)State->ClipboardBuffer; - if (Contents->Type == selection_type_none) - return; - uint64 ClipboardPos = sizeof(clipboard_contents); - ClipboardPos = sizeof(clipboard_contents); - int i = SortedCompInfo->LayerCount - 1; - block_layer *Layer = NULL; - clipboard_channel *Channel; - int b = 0; - 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 (i >= 0) - { - 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! - Assert(0); - /* - for (int h = 0; h < AmountOf(Layer->Property); h++) { - property_channel *Property = &Layer->Property[h]; - 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; - uint16 *ArrayLocation = Property_GetSortedArray(SortedPropertyArray, i, h); - Bezier_Add(Memory, F_Layers, Property, PointData, ArrayLocation); - ClipboardPos += sizeof(bezier_point); - } - b++; - 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_comp_info *SortedCompInfo, sorted_layer *SortedLayerInfo, sorted_property_info *SortedPropertyInfo, uint16 *SortedPropertyArray) -{ - int LocalOffset = 0; - clipboard_contents *Contents = (clipboard_contents *)State->ClipboardBuffer; - *Contents = {}; - Contents->Type = State->RecentSelectionType; - uint64 ClipboardPos = sizeof(clipboard_contents); - if (Contents->Type == selection_type_none) - return; - else if (Contents->Type == selection_type_keyframe) { - for (int i = SortedCompInfo->LayerCount - 1; i >= 0; 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++) { - property_channel *Property = &Layer->Property[h]; - if (Property->IsToggled || Layer->IsSelected) { - sorted_property_info *InfoLocation = Property_GetSortedInfo(SortedPropertyInfo, i, h); - uint16 *ArrayLocation = Property_GetSortedArray(SortedPropertyArray, i, h); - 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) { - 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++; - } - } - if (Channel->KeyframeCount) { - if (!LocalOffset) - LocalOffset = i; - Contents->ChannelCount++; - Channel->LayerOffset = LocalOffset - i; - Assert(0); - // Channel->Name = Property->Name; - } - } - } - } - } - else if (Contents->Type == selection_type_layer) { - } -} - -static void -Layer_Select_Traverse(uint16 PrincipalCompIndex, memory *Memory, project_state *State, int32 IndexToFind, sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray, - int16 RecursionIdx[MAX_PRECOMP_RECURSIONS], int32 *Recursions) -{ - uint16 CompIndex = 0; - if (RecursionIdx[*Recursions] == -1) { - CompIndex = PrincipalCompIndex; - } else { - block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, RecursionIdx[*Recursions]); - CompIndex = Layer->Block_Source_Index; - } - sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, CompIndex); - sorted_comp_info SortedCompInfo = SortedCompArray[CompIndex]; - uint32 RecursionsCurrent = *Recursions; - for (int i = SortedCompInfo.LayerCount - 1; i >= 0; 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); - if (Layer->IsPrecomp && Layer->IsSelected == 2) { - *Recursions = RecursionsCurrent + 1; - RecursionIdx[*Recursions] = Index_Physical; - Layer_Select_Traverse(PrincipalCompIndex, Memory, State, IndexToFind, SortedCompArray, SortedLayerArray, RecursionIdx, Recursions); - } else if (Index_Physical == IndexToFind) { - return; - } - } -} - -static v2 -Layer_TraverseForPoint(project_data *File, project_state *State, memory *Memory, v2 PrincipalCompUV, sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray) -{ - int16 RecursionIdx[MAX_PRECOMP_RECURSIONS] = {}; - RecursionIdx[0] = -1; - int32 Recursions = 0; - sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, File->PrincipalCompIndex); - sorted_comp_info SortedCompInfo = SortedCompArray[File->PrincipalCompIndex]; - block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex); - Layer_Select_Traverse(File->PrincipalCompIndex, Memory, State, State->Brush.LayerToPaint_Index, SortedCompArray, SortedLayerArray, RecursionIdx, &Recursions); - v2 PointUV = {0, 0}; - int OuterWidth = Comp->Width, OuterHeight = Comp->Height; - int InnerWidth = 0, InnerHeight = 0; - if (Recursions == 0) { - block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, State->Brush.LayerToPaint_Index); - layer_transforms T = Layer_GetTransforms(Layer); - Layer_GetDimensions(Memory, Layer, &InnerWidth, &InnerHeight); - PointUV = T_CompUVToLayerUV(T, OuterWidth, OuterHeight, InnerWidth, InnerHeight, PrincipalCompUV); - } else { - for (int i = 1; i <= Recursions; i++) { - block_layer *InnerLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, RecursionIdx[i]); - layer_transforms T = Layer_GetTransforms(InnerLayer); - Layer_GetDimensions(Memory, InnerLayer, &InnerWidth, &InnerHeight); - PointUV = T_CompUVToLayerUV(T, OuterWidth, OuterHeight, InnerWidth, InnerHeight, PrincipalCompUV); - OuterWidth = InnerWidth; - OuterHeight = InnerHeight; - } - } - return PointUV * V2(InnerWidth, InnerHeight); -} - -int32 Layer_TestSelection(memory *Memory, project_state *State, ui *UI, sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray, uint16 PrincipalIndex) -{ - block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, PrincipalIndex); - sorted_comp_info SortedCompInfo = SortedCompArray[PrincipalIndex]; - sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, PrincipalIndex); - int SelectionCount = 0; - int SelectedLayerIndex = 0; - for (int i = SortedCompInfo.LayerCount - 1; i >= 0; 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); - block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index); - layer_transforms T = Layer_GetTransforms(Layer); - v2 UV = T_CompUVToLayerUV(T, Comp->Width, Comp->Height, Source->Width, Source->Height, State->TempZoomRatio); - if (UV.x <= 1.0f && UV.x >= 0.0f && UV.y <= 1.0f && UV.y >= 0.0f && Layer->IsSelected) - { - SelectionCount++; - SelectedLayerIndex = i; - } - } - int32 LayerIndex = -1; - for (int i = SortedCompInfo.LayerCount - 1; i >= 0; 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); - block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index); - layer_transforms T = Layer_GetTransforms(Layer); - v2 UV = T_CompUVToLayerUV(T, Comp->Width, Comp->Height, Source->Width, Source->Height, State->TempZoomRatio); - if (UV.x <= 1.0f && UV.x >= 0.0f && UV.y <= 1.0f && UV.y >= 0.0f && !Layer->IsSelected) - { - if (SelectionCount == 1) { - if (i < SelectedLayerIndex) { - LayerIndex = Index_Physical; - break; - } - } else { - LayerIndex = Index_Physical; - break; - } - } - // if (Layer->IsPrecomp) { - // Layer_RecursiveDeselect(Memory, SortedCompArray, SortedLayerArray, TargetIndex, Layer->Block_Source_Index); - // } - // if (Layer->Block_Composition_Index != TargetIndex) { - // Layer->IsSelected = false; - // } - } - return LayerIndex; -} - -void Layer_RecursiveDeselect(memory *Memory, sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray, uint16 TargetIndex, uint16 PrincipalIndex) -{ - block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, PrincipalIndex); - sorted_comp_info SortedCompInfo = SortedCompArray[PrincipalIndex]; - sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, PrincipalIndex); - for (int i = 0; i < SortedCompInfo.LayerCount; 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); - if (Layer->IsPrecomp) { - Layer_RecursiveDeselect(Memory, SortedCompArray, SortedLayerArray, TargetIndex, Layer->Block_Source_Index); - } - if (Layer->Block_Composition_Index != TargetIndex) { - Layer->IsSelected = false; - } - } -} - -void Property_MinMax_X(memory *Memory, project_state *State, property_channel *Property, - uint16 *ArrayLocation, real32 *Min, real32 *Max) -{ - v2 FirstPointPos[3]; - bezier_point *FirstPointAddress = Bezier_LookupAddress(Memory, Property, ArrayLocation[0]); - Bezier_EvaluateValue(State, FirstPointAddress, FirstPointPos); - *Min = FirstPointPos[0].x; - v2 LastPointPos[3]; - bezier_point *LastPointAddress = Bezier_LookupAddress(Memory, Property, ArrayLocation[Property->Keyframe_Count - 1]); - Bezier_EvaluateValue(State, LastPointAddress, LastPointPos); - *Max = LastPointPos[0].x; -} -void Property_MinMax_Y(memory *Memory, project_state *State, property_channel *Property, - sorted_property_info *PropertyInfo, real32 *Min, real32 *Max, bool32 Evaluate = 1) -{ - if (Evaluate) { - v2 MinYPointPos[3]; - bezier_point *MinYPointAddress = Bezier_LookupAddress(Memory, Property, PropertyInfo->MinYIndex); - Bezier_EvaluateValue(State, MinYPointAddress, MinYPointPos); - *Min = MinYPointPos[0].y; - v2 MaxYPointPos[3]; - bezier_point *MaxYPointAddress = Bezier_LookupAddress(Memory, Property, PropertyInfo->MaxYIndex); - Bezier_EvaluateValue(State, MaxYPointAddress, MaxYPointPos); - *Max = MaxYPointPos[0].y; - } else { - bezier_point *MinYPointAddress = Bezier_LookupAddress(Memory, Property, PropertyInfo->MinYIndex); - *Min = MinYPointAddress->Pos[0].y; - bezier_point *MaxYPointAddress = Bezier_LookupAddress(Memory, Property, PropertyInfo->MaxYIndex); - *Max = MaxYPointAddress->Pos[0].y; - } -} - -inline property_channel * -Effect_Property(memory *Memory, block_effect *Effect, int Offset) -{ - return (property_channel *)Memory_Block_AddressAtIndex(Memory, F_Properties, Effect->Block_Property_Index[Offset]); -}; - -inline v2 Effect_V2(memory *Memory, block_effect *Effect, int Offset) -{ - property_channel *Property_X = (property_channel *)Memory_Block_AddressAtIndex(Memory, F_Properties, Effect->Block_Property_Index[Offset]); - property_channel *Property_Y = (property_channel *)Memory_Block_AddressAtIndex(Memory, F_Properties, Effect->Block_Property_Index[Offset + 1]); - return V2(Property_X->CurrentValue, Property_Y->CurrentValue); -} - -// TODO(fox): Merge with other sorting code. -void Effect_Curves_Sort(memory *Memory, block_effect *Effect, uint16 *SortedPointStart, uint16 Which) -{ - int i = 0; - int SortedPoints = 0; - for (;;) { - property_channel *CurrentProperty = (property_channel *)Memory_Block_AddressAtIndex(Memory, F_Properties, Effect->Block_Property_Index[i]); - v2 Point = Effect_V2(Memory, Effect, i); - uint32 SortedIndex_Playhead = 0; - if (CurrentProperty->Identifier == Which) { - while (SortedIndex_Playhead < SortedPoints) { - uint16 TestPointEntry = SortedPointStart[SortedIndex_Playhead]; - Assert(((property_channel *)Memory_Block_AddressAtIndex(Memory, F_Properties, Effect->Block_Property_Index[TestPointEntry]))->Identifier == Which); - v2 TestPoint = Effect_V2(Memory, Effect, TestPointEntry); - if (Point.x < TestPoint.x) { - break; - } else { - SortedIndex_Playhead += 1; - } - } - if (SortedIndex_Playhead != SortedPoints) { - uint8 *Address_Start = (uint8 *)(SortedPointStart + SortedIndex_Playhead); - uint8 *Address_End = (uint8 *)(SortedPointStart + SortedPoints) - 1; - Arbitrary_ShiftData(Address_Start, Address_End, sizeof(uint16), 1); - } - - uint16 *PointEntry = SortedPointStart + SortedIndex_Playhead; - *PointEntry = i; - SortedPoints++; - } - i += 2; - if (i > (MAX_PROPERTIES_PER_EFFECT - 1)) - break; - } -} - -// The sorting algorithm is straightforward: read every point, evaluate it if -// it's currently being interacted with by the user, record index in a sorted -// list, and repeat, shiftig the list as necessary. - -void Property_SortAll(memory *Memory, project_state *State, property_channel *Property, sorted_property_info *PropertyInfo, uint16 *PropertyArrayStart) -{ - int h = 0, c = 0, i = 0; - uint32 CurrentSortIndex = 0; - real32 MinY = 1000000; - real32 MaxY = -1000000; - int32 Offset = (State->Interact_Active == interact_type_keyframe_move) ? (int32)State->Interact_Offset[0] : 0; - while (Block_Loop(Memory, Property, Property->Keyframe_Count, &h, &c, &i)) { - v2 PointPos[3]; - bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, i); - - Bezier_EvaluateValue(State, PointAddress, PointPos); - - if (MinY > PointAddress->Pos[0].y) { - MinY = PointAddress->Pos[0].y; - PropertyInfo->MinYIndex = i; - } - if (MaxY < PointAddress->Pos[0].y) { - MaxY = PointAddress->Pos[0].y; - PropertyInfo->MaxYIndex = i; - } - - uint32 SortedIndex_Playhead = 0; - while (SortedIndex_Playhead < CurrentSortIndex) { - uint16 TestPointEntry = PropertyArrayStart[SortedIndex_Playhead]; - v2 TestPointPos[3]; - bezier_point *TestPointAddress = Bezier_LookupAddress(Memory, Property, TestPointEntry); - Bezier_EvaluateValue(State, TestPointAddress, TestPointPos); - if (PointPos[0].x < TestPointPos[0].x ) { - break; - } else { - SortedIndex_Playhead++; - } - } - if (SortedIndex_Playhead != CurrentSortIndex) { - uint8 *Address_Start = (uint8 *)(PropertyArrayStart + SortedIndex_Playhead); - uint8 *Address_End = (uint8 *)(PropertyArrayStart + CurrentSortIndex) - 1; - Assert(CurrentSortIndex != Property->Keyframe_Count); - Arbitrary_ShiftData(Address_Start, Address_End, sizeof(uint16), 1); - } - uint16 *PointEntry = PropertyArrayStart + SortedIndex_Playhead; - *PointEntry = i; - CurrentSortIndex++; - } -} - -void Property_DeselectAll(project_data *File, project_state *State, memory *Memory, - sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray, - sorted_property_info *SortedPropertyInfo, uint16 *SortedPropertyArray) -{ - 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) - continue; - sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, Layer->Block_Composition_Index); - sorted_property_info *InfoLocation = SortedPropertyInfo + SortedLayerInfo->SortedPropertyStart; - uint16 *ArrayLocation = SortedPropertyArray + SortedLayerInfo->SortedKeyframeStart; - int h = 0, c = 0, p = 0; - property_channel *Property = NULL; - block_effect *Effect = NULL; - while (Layer_LoopChannels(State, Memory, &InfoLocation, &ArrayLocation, Layer, &Property, &Effect, &h, &c, &p)) - { - for (int p = 0; p < Property->Keyframe_Count; p++) { - int k = ArrayLocation[p]; - bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, k); - PointAddress->IsSelected = 0; - } - } - } -} - -void Layer_Sort_CheckPrev(memory *Memory, int i, int Direction, sorted_layer *SortedLayerInfo, sorted_comp_info SortedCompInfo, int *EntriesPassed, sorted_layer *LayerEntry, bool32 AltMethod) -{ - int PrevOffsetIndex = i + Direction + (*EntriesPassed * Direction); - bool32 OutOfBounds = (Direction > 0) ? (PrevOffsetIndex > (SortedCompInfo.LayerCount - 1)) : (PrevOffsetIndex < 0); - if (!OutOfBounds) { - sorted_layer *PrevLayerEntry = &SortedLayerInfo[PrevOffsetIndex]; - real32 PrevOffset = PrevLayerEntry->SortedOffset; - if (PrevOffset == (LayerEntry->SortedOffset - Direction)) { - (*EntriesPassed)++; - if (!AltMethod) { - PrevLayerEntry->SortedOffset += Direction; - } else { - LayerEntry->SortedOffset -= Direction; - Layer_Sort_CheckPrev(Memory, i, Direction, SortedLayerInfo, SortedCompInfo, EntriesPassed, LayerEntry, AltMethod); - } - } - } -} - -void Layer_Evaluate_Display(project_state *State, memory *Memory, block_layer *Layer, - sorted_property_info *SortedPropertyInfo, uint16 *SortedPropertyArray, - sorted_layer *LayerArrayStart, sorted_comp_info *CompStart, sorted_layer *SortedLayerInfo, - int i, real32 *Offset) -{ - int ExtraPad = 1; - sorted_property_info *InfoLocation = SortedPropertyInfo + SortedLayerInfo->SortedPropertyStart; - uint16 *ArrayLocation = SortedPropertyArray + SortedLayerInfo->SortedKeyframeStart; - int h = 0, c = 0, p = 0; - property_channel *Property = NULL; - block_effect *Effect = NULL; - while (Layer_LoopChannels(State, Memory, &InfoLocation, &ArrayLocation, Layer, &Property, &Effect, &h, &c, &p)) - { - if (Property->IsToggled) { - *Offset += 1 + ExtraPad; - ExtraPad = 0; - } - } - /* - if (Layer->Precomp_Toggled) { - Assert(Layer->IsPrecomp); - sorted_comp_info *Layer_SortedCompInfo = &CompStart[Layer->Block_Source_Index]; - sorted_layer *Layer_SortedLayerInfo = Layer_GetSortedArray(LayerArrayStart, CompStart, Layer->Block_Source_Index); - sorted_layer *TopLayerEntry = &Layer_SortedLayerInfo[0]; - sorted_layer *BottomLayerEntry = &Layer_SortedLayerInfo[Layer_SortedCompInfo->LayerCount - 1]; - *Offset += TopLayerEntry->SortedOffset - BottomLayerEntry->SortedOffset + 2; - } - */ -} - -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. - -void Layer_SortAll(project_data *File, project_state *State, memory *Memory, - sorted_layer *LayerArrayStart, sorted_comp_info *CompStart, - uint32 LayerCount, uint32 CompCount) -{ - 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); - Assert(Layer->Block_Composition_Index < CompCount); - CompStart[Layer->Block_Composition_Index].LayerCount++; - } - 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); - sorted_comp_info *SortedCompInfo = &CompStart[Layer->Block_Composition_Index]; - sorted_layer *SortedLayerInfo = Layer_GetSortedArray(LayerArrayStart, CompStart, Layer->Block_Composition_Index); - uint32 SortedIndex_Playhead = 0; - while (SortedIndex_Playhead < SortedCompInfo->CurrentSortIndex) { - sorted_layer LayerEntry = SortedLayerInfo[SortedIndex_Playhead]; - block_layer *TestLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, LayerEntry.Block_Layer_Index); - if (-Layer->Vertical_Offset < -TestLayer->Vertical_Offset) { - break; - } else { - SortedIndex_Playhead++; - } - } - if (SortedIndex_Playhead != SortedCompInfo->CurrentSortIndex) { - uint8 *Address_Start = (uint8 *)(SortedLayerInfo + SortedIndex_Playhead); - uint8 *Address_End = (uint8 *)(SortedLayerInfo + SortedCompInfo->CurrentSortIndex) - 1; - Assert(SortedCompInfo->CurrentSortIndex != SortedCompInfo->LayerCount); - Arbitrary_ShiftData(Address_Start, Address_End, sizeof(sorted_layer), 1); - } - sorted_layer *LayerEntry = SortedLayerInfo + SortedIndex_Playhead; - LayerEntry->Block_Layer_Index = i; - LayerEntry->SortedOffset = Layer->Vertical_Offset; - SortedCompInfo->CurrentSortIndex++; - } - if (State->Interact_Active == interact_type_layer_move) { - int32 Offset = (int32)State->Interact_Offset[1]; - bool32 Direction = (Offset > 0) ? 1 : -1; - for (uint32 c = 0; c < CompCount; c++) { - sorted_comp_info *SortedCompInfo = &CompStart[c]; - if (!SortedCompInfo->LayerCount) - continue; - sorted_layer *SortedLayerInfo = Layer_GetSortedArray(LayerArrayStart, CompStart, c); - int i = (Direction > 0) ? SortedCompInfo->LayerCount - 1 : 0; - bool32 Case = 1; - while (Case) { - int32 EntriesPassed = 0; - sorted_layer *LayerEntry = &SortedLayerInfo[i]; - block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, LayerEntry->Block_Layer_Index); - Assert(LayerEntry->SortedOffset == Layer->Vertical_Offset); - if (Layer->IsSelected) { - int32 SpacesToMove = Offset * Direction; - while (SpacesToMove) { - Layer_Sort_CheckPrev(Memory, i, Direction, SortedLayerInfo, *SortedCompInfo, &EntriesPassed, LayerEntry, 0); - LayerEntry->SortedOffset -= Direction; - SpacesToMove--; - } - } - int b = 0; - while (b < EntriesPassed) { - sorted_layer *FrontEntry = &SortedLayerInfo[i+(b*Direction)]; - sorted_layer *BackEntry = &SortedLayerInfo[i+((b+1)*Direction)]; - sorted_layer Swap = *FrontEntry; - *FrontEntry = *BackEntry; - *BackEntry = Swap; - b++; - } - i -= Direction; - Case = (Direction > 0) ? (i >= 0) : (i < SortedCompInfo->LayerCount); - } - } - } -} - -// NOTE(fox): We could be slightly more efficient and just allocate redundant data -// instead of having another loop. -void LayerProperty_Allocate(project_data *File, project_state *State, memory *Memory, sorted_layer *LayerArrayStart, - sorted_comp_info *CompStart, uint32 LayerCount, uint32 CompCount, - uint32 *TotalPropertyCount, uint32 *TotalKeyframeCount) -{ - uint32 SortedPropertyPlayhead = 0; - uint32 SortedKeyframePlayhead = 0; - for (int c = 0; c < CompCount; c++) { - sorted_comp_info SortedCompInfo = CompStart[c]; - sorted_layer *SortedLayerInfo = Layer_GetSortedArray(LayerArrayStart, CompStart, c); - for (int i = 0; i < SortedCompInfo.LayerCount; i++) { - sorted_layer *SortedLayer = &SortedLayerInfo[i]; - block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, SortedLayer->Block_Layer_Index); - SortedLayer->SortedPropertyStart = SortedPropertyPlayhead; - SortedLayer->SortedKeyframeStart = SortedKeyframePlayhead; - for (int h = 0; h < AmountOf(Layer->Property); h++) { - property_channel *Property = &Layer->Property[h]; - if (Property->Keyframe_Count) { - SortedKeyframePlayhead += Property->Keyframe_Count; - } - SortedPropertyPlayhead++; - } - for (int i = 0; i < Layer->Block_Effect_Count; i++) { - block_effect Effect = *(block_effect *)Memory_Block_AddressAtIndex(Memory, F_Effects, Layer->Block_Effect_Index[i]); - header_effect *EffectHeader = Effect_EntryFromID(State, Effect.ID); - for (int h = 0; h < EffectHeader->Property_Count; h++) { - header_property ChannelHeader = State->Property[EffectHeader->PropertyStartIndex + h]; - property_channel *Property = (property_channel *)Memory_Block_AddressAtIndex(Memory, F_Properties, Effect.Block_Property_Index[h]); - if (Property->Keyframe_Count) { - SortedKeyframePlayhead += Property->Keyframe_Count; - } - SortedPropertyPlayhead++; - } - } - } - } -} - -void LayerProperty_SortAll(project_data *File, project_state *State, memory *Memory, sorted_layer *LayerArrayStart, - sorted_comp_info *CompStart, sorted_property_info *SortedPropertyInfo, uint16 *SortedPropertyArray, - uint32 LayerCount, uint32 CompCount) -{ - uint32 SortedPropertyPlayhead = 0; - uint32 SortedKeyframePlayhead = 0; - for (int c = 0; c < CompCount; c++) { - sorted_comp_info SortedCompInfo = CompStart[c]; - sorted_layer *SortedLayerInfo = Layer_GetSortedArray(LayerArrayStart, CompStart, c); - for (int i = 0; i < SortedCompInfo.LayerCount; i++) { - sorted_layer *SortedLayer = &SortedLayerInfo[i]; - block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, SortedLayer->Block_Layer_Index); - SortedLayer->SortedPropertyStart = SortedPropertyPlayhead; - SortedLayer->SortedKeyframeStart = SortedKeyframePlayhead; - for (int h = 0; h < AmountOf(Layer->Property); h++) { - property_channel *Property = &Layer->Property[h]; - if (Property->Keyframe_Count) { - sorted_property_info *InfoLocation = SortedPropertyInfo + SortedPropertyPlayhead; - uint16 *ArrayLocation = SortedPropertyArray + SortedKeyframePlayhead; - Property_SortAll(Memory, State, Property, InfoLocation, ArrayLocation); - SortedKeyframePlayhead += Property->Keyframe_Count; - } - SortedPropertyPlayhead++; - } - for (int i = 0; i < Layer->Block_Effect_Count; i++) { - block_effect Effect = *(block_effect *)Memory_Block_AddressAtIndex(Memory, F_Effects, Layer->Block_Effect_Index[i]); - header_effect *EffectHeader = Effect_EntryFromID(State, Effect.ID); - for (int h = 0; h < EffectHeader->Property_Count; h++) { - header_property ChannelHeader = State->Property[EffectHeader->PropertyStartIndex + h]; - property_channel *Property = (property_channel *)Memory_Block_AddressAtIndex(Memory, F_Properties, Effect.Block_Property_Index[h]); - if (Property->Keyframe_Count) { - sorted_property_info *InfoLocation = SortedPropertyInfo + SortedPropertyPlayhead; - uint16 *ArrayLocation = SortedPropertyArray + SortedKeyframePlayhead; - Property_SortAll(Memory, State, Property, InfoLocation, ArrayLocation); - SortedKeyframePlayhead += Property->Keyframe_Count; - } - SortedPropertyPlayhead++; - } - } - } - } - int a = 0; -} - -sorted_file File_Sort_Push(project_data *File, project_state *State, memory *Memory) -{ - sorted_file Sorted = {0}; - Sorted.Layer_SortSize = (sizeof(sorted_comp_info) * File->Comp_Count) + - (sizeof(sorted_layer) * File->Layer_Count); - void *Layer_SortedArray = Memory_PushScratch(Memory, Sorted.Layer_SortSize); - Arbitrary_Zero((uint8 *)Layer_SortedArray, Sorted.Layer_SortSize); - Sorted.CompArray = (sorted_comp_info *)Layer_SortedArray; - Sorted.LayerArray = (sorted_layer *)((uint8 *)Layer_SortedArray + (sizeof(sorted_comp_info) * File->Comp_Count)); - - 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; - - uint32 TotalPropertyCount = 0; - uint32 TotalKeyframeCount = 0; - LayerProperty_Allocate(File, State, Memory, Sorted.LayerArray, Sorted.CompArray, File->Layer_Count, File->Comp_Count, &TotalPropertyCount, &TotalKeyframeCount); - uint64 PropertyInfoSize = TotalPropertyCount * sizeof(sorted_property_info); - uint64 PropertyArraySize = TotalKeyframeCount * sizeof(uint16); - Sorted.Property_SortSize = PropertyArraySize + PropertyInfoSize; - void *Property_SortedArray = Memory_PushScratch(Memory, Sorted.Property_SortSize); - Arbitrary_Zero((uint8 *)Property_SortedArray, Sorted.Property_SortSize); - Sorted.PropertyInfo = (sorted_property_info *)Property_SortedArray; - Sorted.PropertyArray = (uint16 *)((uint8 *)Property_SortedArray + PropertyInfoSize); - - TempSource_SortAll(File, State, Memory, Sorted.SourceArray, &Sorted.TempSourceCount); - Layer_SortAll(File, State, Memory, Sorted.LayerArray, Sorted.CompArray, File->Layer_Count, File->Comp_Count); - LayerProperty_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, uint64 Source_SortSize) -{ - Memory_PopScratch(Memory, Property_SortSize); - Memory_PopScratch(Memory, Source_SortSize); - Memory_PopScratch(Memory, Layer_SortSize); -} - -// lots of cleanup... -static void -Layer_Delete(project_data *File, project_state *State, memory *Memory, uint32 Index) -{ - block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index); - History_Action_Block_Swap(Memory, F_Layers, Layer); - Layer->Occupied = 0; - - block_string *String = (block_string *)Memory_Block_AddressAtIndex(Memory, F_Strings, Layer->Block_String_Index, 0); - History_Action_Block_Swap(Memory, F_Strings, String); - String->Occupied = 0; - - for (int i = 0; i < Layer->Block_Effect_Count; i++) { - block_effect *Effect = (block_effect *)Memory_Block_AddressAtIndex(Memory, F_Effects, Layer->Block_Effect_Index[i]); - header_effect *EffectHeader = Effect_EntryFromID(State, Effect->ID); - for (int h = 0; h < EffectHeader->Property_Count; h++) { - header_property ChannelHeader = State->Property[EffectHeader->PropertyStartIndex + h]; - property_channel *Property = (property_channel *)Memory_Block_AddressAtIndex(Memory, F_Properties, Effect->Block_Property_Index[h]); - if (Property->Block_Bezier_Count) { - block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, Property->Block_Bezier_Index[i], 0); - History_Action_Block_Swap(Memory, F_Bezier, Bezier); - Bezier->Occupied = 0; - } - History_Action_Block_Swap(Memory, F_Properties, Property); - Property->Occupied = 0; - } - History_Action_Block_Swap(Memory, F_Effects, Effect); - Effect->Occupied = 0; - } - History_Action_Swap(Memory, F_File, sizeof(File->Layer_Count), &File->Layer_Count); - File->Layer_Count--; -} - -static void -Project_Layer_Delete(project_data *File, project_state *State, memory *Memory) -{ - bool32 CommitAction = 0; - int h = 0, c = 0, i = 0; - int LayerCount = File->Layer_Count; - while (Block_Loop(Memory, F_Layers, LayerCount, &h, &c, &i)) { - block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); - if (Layer->IsSelected) { - if (!CommitAction) { - History_Entry_Commit(Memory, "Delete layer"); - CommitAction = 1; - } - Layer_Delete(File, State, Memory, i); - } - } - if (CommitAction) { - History_Entry_End(Memory); - State->UpdateFrame = true; - State->MostRecentlySelectedLayer = -1; - } -} - -static bool32 -Property_IsGraphSelected(memory *Memory, property_channel *Property, uint16 *ArrayLocation) -{ - for (int p = 0; p < Property->Keyframe_Count; p++) { - int k = ArrayLocation[p]; - bezier_point *Point = Bezier_LookupAddress(Memory, Property, k); - if (Point->IsSelected) - return 1; - } - return 0; -} - -block_layer * Layer_Init(project_data *File, memory *Memory) -{ - if (File->Layer_Count + 1 > MAX_LAYERS) { - Assert(0); - } - block_layer *Layer = (block_layer *)Memory_Block_AllocateAddress(Memory, F_Layers); - History_Action_Block_Swap(Memory, F_Layers, Layer); - - *Layer = {}; - Layer->Occupied = 1; - - Layer->Block_String_Index = Memory_Block_AllocateNew(Memory, F_Strings); - block_string *String = (block_string *)Memory_Block_AddressAtIndex(Memory, F_Strings, Layer->Block_String_Index, 0); - sprintf(String->Char, "Layer %i", File->Layer_Count + 1); // CSbros... - History_Action_Swap(Memory, F_File, sizeof(String->Occupied), &String->Occupied); - String->Occupied = 1; - - Layer->x = Property_InitFloat(0.0f, 1.0f); - Layer->y = Property_InitFloat(0.0f, 1.0f); - Layer->ax = Property_InitFloat(0.5f, 0.005f); - Layer->ay = Property_InitFloat(0.5f, 0.005f); - Layer->scale = Property_InitFloat(1.0f, 0.005f); - Layer->rotation = Property_InitFloat(0.0f, 1.0f); - Layer->opacity = Property_InitFloat(1.0f, 0.005f, 0.0f, 1.0f); - Layer->time = Property_InitFloat(0.0f, 1.0f, 0, 100000, 1); - - Layer->IsVisible = 1; - - History_Action_Swap(Memory, F_File, sizeof(File->Layer_Count), &File->Layer_Count); - File->Layer_Count++; - - return Layer; -} - -static int -Layer_GetTopOffset(project_data *File, memory *Memory) -{ - int TopOffset = 9999; - 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->Block_Composition_Index == File->PrincipalCompIndex) { - TopOffset = (Layer->Vertical_Offset < TopOffset) ? Layer->Vertical_Offset : TopOffset; - } - } - return TopOffset; -} - -static void -Project_PaintLayer_New(project_data *File, project_state *State, memory *Memory) -{ - int TopOffset = Layer_GetTopOffset(File, Memory); - block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex); - Arbitrary_Zero((uint8 *)State->Brush.TransientBitmap, 2048*2048*4); - State->Interact_Active = interact_type_brush; - Layer_DeselectAll(File, State, Memory); - History_Entry_Commit(Memory, "Paint new layer"); - uint16 i = Source_Generate_Blank(File, State, Memory, MainComp->Width, MainComp->Height, MainComp->BytesPerPixel); - block_layer *Layer = Layer_Init(File, Memory); - block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index); - State->Brush.LayerToPaint_Index = Memory_Block_LazyIndexAtAddress(Memory, F_Layers, (void *)Layer); - Layer->Block_Source_Index = i; - Layer->x.CurrentValue = MainComp->Width / 2; - Layer->y.CurrentValue = MainComp->Height / 2; - if (File->Layer_Count == 1) { - Layer->Vertical_Offset = 11 - 1; - } else { - Layer->Vertical_Offset = TopOffset - 1; - } - Layer->Frame_Start = MainComp->Frame_Start; - Layer->Frame_End = MainComp->Frame_End; - Layer_Select(Memory, State, Memory_Block_LazyIndexAtAddress(Memory, F_Layers, Layer)); - History_Entry_End(Memory); - State->UpdateFrame = true; -} - -void Source_UICreateButton(project_data *File, project_state *State, memory *Memory) -{ - block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex); - int TopOffset = Layer_GetTopOffset(File, Memory); - bool32 CommitAction = 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->IsSelected) { - if (!CommitAction) { - History_Entry_Commit(Memory, "Create layer from source"); - CommitAction = 1; - } - if (Source->Type == source_type_principal_temp) { - History_Action_Swap(Memory, F_File, sizeof(Source->Type), &Source->Type); - Source->Type = source_type_principal; - } - block_layer *Layer = Layer_Init(File, Memory); - Layer->Block_Source_Index = i; - Layer->x.CurrentValue = Comp->Width/2; - Layer->y.CurrentValue = Comp->Height/2; - Layer->Vertical_Offset = TopOffset-1; - Layer->Frame_Start = Comp->Frame_Start; - Layer->Frame_End = Comp->Frame_End; - TopOffset--; - } - State->UpdateFrame = true; - } - if (CommitAction) - History_Entry_End(Memory); - Source_DeselectAll(File, Memory); -} - -void Precomp_UIDuplicate(project_data *File, project_state *State, memory *Memory, uint16 CompIndex, - sorted_comp_info SortedCompInfo, sorted_layer *SortedLayerInfo) -{ - block_layer *Layer = NULL; - for (int i = SortedCompInfo.LayerCount - 1; i >= 0; i--) - { - sorted_layer SortEntry = SortedLayerInfo[i]; - uint32 Index_Physical = SortEntry.Block_Layer_Index; - Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); - if (Layer->IsSelected) { - break; - } - } - if (Layer) { - block_layer *DupeLayer = Layer_Init(File, Memory); - *DupeLayer = *Layer; - DupeLayer->Vertical_Offset += 1; - for (int h = 0; h < AmountOf(Layer->Property); h++) { - property_channel *Property = &Layer->Property[h]; - if (Property->Block_Bezier_Count) { - property_channel *DupeProperty = &DupeLayer->Property[h]; - DupeProperty->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 *DupeBezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, DupeProperty->Block_Bezier_Index[0], 0); - Bezier->Occupied = true; - *DupeBezier = *Bezier; - } - } - } -} - -void Precomp_UIDelete(project_data *File, project_state *State, memory *Memory, uint16 CompIndex, - sorted_comp_info SortedCompInfo, sorted_layer *SortedLayerInfo) -{ - block_layer *Layer = NULL; - for (int i = SortedCompInfo.LayerCount - 1; i >= 0; i--) - { - sorted_layer SortEntry = SortedLayerInfo[i]; - uint32 Index_Physical = SortEntry.Block_Layer_Index; - Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); - if (Layer->IsSelected) { - } - } -} - -void Precomp_UICreateButton(project_data *File, project_state *State, memory *Memory, uint16 CompIndex, - sorted_comp_info SortedCompInfo, sorted_layer *SortedLayerInfo) -{ - block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, CompIndex); - History_Entry_Commit(Memory, "Pre-compose layer"); - block_composition *NewComp = Precomp_Init(File, Memory); - NewComp->Width = Comp->Width; - NewComp->Height = Comp->Height; - NewComp->FPS = Comp->FPS; - NewComp->BytesPerPixel = Comp->BytesPerPixel; - NewComp->Frame_Count = Comp->Frame_Count; - NewComp->Frame_Start = Comp->Frame_Start; - NewComp->Frame_End = Comp->Frame_End; - int32 TopOffset = 0; - for (int i = SortedCompInfo.LayerCount - 1; i >= 0; 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); - if (Layer->IsSelected) { - TopOffset = Layer->Vertical_Offset; - break; - } - } - for (int i = SortedCompInfo.LayerCount - 1; i >= 0; 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); - if (Layer->IsSelected) { - History_Action_Swap(Memory, F_File, sizeof(Layer->Block_Composition_Index), &Layer->Block_Composition_Index); - Layer->Block_Composition_Index = File->Comp_Count - 1; - } - } - block_layer *PrecompLayer = Layer_Init(File, Memory); - bezier_point Point0 = { 1, {0, 0, 1, 0, 1, 0}, interpolation_type_linear, 0, {0, 0, 0}, 0 }; - bezier_point Point1 = { 1, {(real32)NewComp->Frame_End, (real32)NewComp->Frame_End, 1, 0, 1, 0}, interpolation_type_linear, 0, {0, 0, 0}, 0 }; - Bezier_Add(Memory, F_Layers, &PrecompLayer->time, Point0, NULL); - Bezier_Add(Memory, F_Layers, &PrecompLayer->time, Point1, NULL); - PrecompLayer->IsPrecomp = true; - Layer_Select(Memory, State, Memory_Block_LazyIndexAtAddress(Memory, F_Layers, PrecompLayer)); - PrecompLayer->Block_Source_Index = File->Comp_Count - 1; - PrecompLayer->Block_Composition_Index = CompIndex; - PrecompLayer->Vertical_Offset = TopOffset; - PrecompLayer->Frame_End = NewComp->Frame_End; - PrecompLayer->ColIndex = 3; - PrecompLayer->x.CurrentValue = Comp->Width/2; - PrecompLayer->y.CurrentValue = Comp->Height/2; - History_Entry_End(Memory); - State->UpdateFrame = true; -} - - -// Helper for working with different bit depths. -static render_byte_info -Bitmap_ByteInfo(uint32 BytesPerPixel) { - render_byte_info Byte = {}; - if (BytesPerPixel == 4) { - Byte.MaskPixel = 0xFF; - Byte.ByteOffset = 1; - Byte.Normalized = 1 / 255.0f; - Byte.Bits = 255; - } else if (BytesPerPixel == 8) { - Byte.MaskPixel = 0xFFFF; - Byte.ByteOffset = 2; - Byte.Normalized = 1 / 65535.0f; - Byte.Bits = 65535; - } else { - Byte.MaskPixel = 0xFFFFFFFF; - Byte.ByteOffset = 4; - Byte.Normalized = 1 / 4294967295.0f; - Byte.Bits = 4294967295; - Assert(0); - } - return Byte; -} - -// TODO(fox): Make separate full-size bitmap that gets scaled on the GPU instead of this -static void -State_BindBrushTexture(memory *Memory, brush_state *Brush, uint32 BytesPerPixel) -{ - GL_GenAndBindTexture(&Brush->GLTexture, Brush->Size, Brush->Size, BytesPerPixel, Brush->PaintBuffer); -} - -static void -Brush_CalcBitmapAlphaFromSize(memory *Memory, brush_state *Brush, uint32 BytesPerPixel) -{ - int32 BrushLength = Brush->Size; - if (BrushLength > 128) { - BrushLength = BrushLength + (16 - (BrushLength % 16)); - } - real32 BrushCenter = (real32)BrushLength / 2; - real32 MaxLength = BrushCenter; - void *BrushAddress = Brush->PaintBuffer; - - render_byte_info Byte = Bitmap_ByteInfo(BytesPerPixel); - - for (int Y = 0; Y < BrushLength; Y++) { - for (int X = 0; X < BrushLength; X++) { - uint8 *PixelAddress = (uint8 *)BrushAddress + (Y * BytesPerPixel*BrushLength) + (X * BytesPerPixel); - uint32 *R_DestAddress = (uint32 *)(PixelAddress + Byte.ByteOffset*0); - // uint32 *G_DestAddress = (uint32 *)(PixelAddress + Byte.ByteOffset*1); - // uint32 *B_DestAddress = (uint32 *)(PixelAddress + Byte.ByteOffset*2); - uint32 *A_DestAddress = (uint32 *)(PixelAddress + Byte.ByteOffset*3); - v2 Pos = V2(BrushCenter - X, BrushCenter - Y); - real32 L = sqrt(LengthSq(Pos)); - real32 Gradient = Ceil(L, MaxLength) / MaxLength; - Gradient = pow(Gradient, Brush->Hardness); - // Gradient = (Gradient >= 0.04045) ? pow((Gradient + 0.055) / (1 + 0.055), 2.4) : Gradient / 12.92; - // Gradient = (Gradient >= 0.0031308) ? (1.055) * pow(Gradient, (1.0/2.4)) - 0.055 : 12.92 * Gradient; - *R_DestAddress = (*R_DestAddress & ~Byte.MaskPixel) | Byte.Bits; // brush preview is red - *A_DestAddress = (*A_DestAddress & ~Byte.MaskPixel) | (uint32)((1.0f - Gradient)*Byte.Bits); - } - } -} - -// Imported bitmaps are stored in linear, and all ops are also done in linear. -static void -Bitmap_SRGBToLinear(void *Buffer, uint16 Width, uint16 Height, uint16 BytesPerPixel, bool32 ToLinear) -{ - uint8 *Row = (uint8 *)Buffer; - uint64 TotalBytes = Width * Height * BytesPerPixel; - - render_byte_info LayerBits = Bitmap_ByteInfo(BytesPerPixel); - - uint64 bytes = 0; - while (bytes < TotalBytes) { - uint8 *LayerPixel = Row + bytes; - uint32 *R_DestAddress = (uint32 *)(LayerPixel + LayerBits.ByteOffset * 0); - uint32 *G_DestAddress = (uint32 *)(LayerPixel + LayerBits.ByteOffset * 1); - uint32 *B_DestAddress = (uint32 *)(LayerPixel + LayerBits.ByteOffset * 2); - uint32 *A_DestAddress = (uint32 *)(LayerPixel + LayerBits.ByteOffset * 3); - - real32 TexR = (real32)(*R_DestAddress & LayerBits.MaskPixel) * LayerBits.Normalized; - real32 TexG = (real32)(*G_DestAddress & LayerBits.MaskPixel) * LayerBits.Normalized; - real32 TexB = (real32)(*B_DestAddress & LayerBits.MaskPixel) * LayerBits.Normalized; - real32 TexA = (real32)(*A_DestAddress & LayerBits.MaskPixel) * LayerBits.Normalized; - - if (ToLinear) { - TexR = (TexR >= 0.04045) ? pow((TexR + 0.055) / (1 + 0.055), 2.4) : TexR / 12.92; - TexG = (TexG >= 0.04045) ? pow((TexG + 0.055) / (1 + 0.055), 2.4) : TexG / 12.92; - TexB = (TexB >= 0.04045) ? pow((TexB + 0.055) / (1 + 0.055), 2.4) : TexB / 12.92; - TexA = (TexA >= 0.04045) ? pow((TexA + 0.055) / (1 + 0.055), 2.4) : TexA / 12.92; - } else { - TexR = (TexR >= 0.0031308) ? (1.055) * pow(TexR, (1.0/2.4)) - 0.055 : 12.92 * TexR; - TexG = (TexG >= 0.0031308) ? (1.055) * pow(TexG, (1.0/2.4)) - 0.055 : 12.92 * TexG; - TexB = (TexB >= 0.0031308) ? (1.055) * pow(TexB, (1.0/2.4)) - 0.055 : 12.92 * TexB; - TexA = (TexA >= 0.0031308) ? (1.055) * pow(TexA, (1.0/2.4)) - 0.055 : 12.92 * TexA; - } - - uint32 R_Out = (uint32)(Normalize(TexR) * LayerBits.Bits); - uint32 G_Out = (uint32)(Normalize(TexG) * LayerBits.Bits); - uint32 B_Out = (uint32)(Normalize(TexB) * LayerBits.Bits); - uint32 A_Out = (uint32)(Normalize(TexA) * LayerBits.Bits); - - *R_DestAddress = (*R_DestAddress & ~LayerBits.MaskPixel) | R_Out; - *G_DestAddress = (*G_DestAddress & ~LayerBits.MaskPixel) | G_Out; - *B_DestAddress = (*B_DestAddress & ~LayerBits.MaskPixel) | B_Out; - *A_DestAddress = (*A_DestAddress & ~LayerBits.MaskPixel) | A_Out; - bytes += BytesPerPixel; - } -} - -static void -Brush_Info(brush_info *B, brush_state *Brush, block_source *Source, void *SourceBuffer, v2 LayerPos, v4 Color) -{ - B->BrushLength = (uint32)Brush->Size; - if (B->BrushLength > 128) { - B->BrushLength = B->BrushLength + (16 - (B->BrushLength % 16)); - } - - rectangle RenderRegion = { 0, 0, Source->Width, Source->Height }; - rectangle BrushPos = { (int32)(LayerPos.x - (B->BrushLength / 2)), - (int32)(LayerPos.y - (B->BrushLength / 2)), - (int32)(LayerPos.x + (B->BrushLength / 2)), - (int32)(LayerPos.y + (B->BrushLength / 2)) }; - - B->LayerBounds = ClipRectangle(BrushPos, RenderRegion); - - if (BrushPos.Min.x < Brush->CacheBounds.Min.x) - Brush->CacheBounds.Min.x = BrushPos.Min.x; - if (BrushPos.Min.y < Brush->CacheBounds.Min.y) - Brush->CacheBounds.Min.y = BrushPos.Min.y; - if (BrushPos.Max.x > Brush->CacheBounds.Max.x) - Brush->CacheBounds.Max.x = BrushPos.Max.x; - if (BrushPos.Max.y > Brush->CacheBounds.Max.y) - Brush->CacheBounds.Max.y = BrushPos.Max.y; - - Assert(Source->Type == source_type_principal); - - B->BytesPerPixel = 4; - B->SourceWidth = Source->Width; - B->SourceBytesPerPixel = Source->BytesPerPixel; - B->SourceBuffer = SourceBuffer; - - Assert(Source->BytesPerPixel == 4); - - B->LayerPitch = Source->Width*Source->BytesPerPixel; - B->BrushPitch = (int)B->BrushLength * B->BytesPerPixel; - - B->LayerBits = Bitmap_ByteInfo(Source->BytesPerPixel); - B->BrushBits = Bitmap_ByteInfo(B->BytesPerPixel); - - B->ExtraX = 0; - B->ExtraY = 0; - if (BrushPos.Min.x < 0) { - B->ExtraX = BrushPos.Min.x; - } - if (BrushPos.Min.y < 0) { - B->ExtraY = BrushPos.Min.y; - } - - B->BrushBuffer = Brush->PaintBuffer; - B->EraseMode = Brush->EraseMode; - - B->R_Brush = (Color.r >= 0.04045) ? pow((Color.r + 0.055) / (1 + 0.055), 2.4) : Color.r / 12.92; - B->G_Brush = (Color.g >= 0.04045) ? pow((Color.g + 0.055) / (1 + 0.055), 2.4) : Color.g / 12.92; - B->B_Brush = (Color.b >= 0.04045) ? pow((Color.b + 0.055) / (1 + 0.055), 2.4) : Color.b / 12.92; - B->A_Brush = (Color.a >= 0.04045) ? pow((Color.a + 0.055) / (1 + 0.055), 2.4) : Color.a / 12.92; - - B->BrushRow = (uint8 *)B->BrushBuffer; -} - -void Bitmap_SwapData(uint8 *Address_0, uint8 *Address_1, uint64 Size, uint16 BytesPerPixel) -{ - uint64 i = 0; - uint16 ByteOffset = Bitmap_ByteInfo(BytesPerPixel).ByteOffset; - uint64 RemainderBytes = Size % ByteOffset; - Assert(BytesPerPixel == 4); - - while (i < Size) { - uint32 *Pixel_0 = (uint32 *)(Address_0 + i); - uint32 *Pixel_1 = (uint32 *)(Address_1 + i); - if (*Pixel_0 != 0x00000000) { - uint32 Temp = *Pixel_1; - *Pixel_1 = *Pixel_0; - *Pixel_0 = Temp; - } - i += sizeof(uint32); - } -} - - -static void -PaintTest(brush_info B, void *CacheBuffer, rectangle RenderRegion) -{ - for (int32 Y = RenderRegion.Min.y; Y < RenderRegion.Max.y; Y++) { - for (int32 X = RenderRegion.Min.x; X < RenderRegion.Max.x; X++) { - - uint32 Offset = Y*B.LayerPitch + X*B.SourceBytesPerPixel; - uint8 *LayerPixel = (uint8 *)CacheBuffer + Offset; - - uint32 *R_DestAddress = (uint32 *)(LayerPixel + B.LayerBits.ByteOffset * 0); - uint32 *G_DestAddress = (uint32 *)(LayerPixel + B.LayerBits.ByteOffset * 1); - uint32 *B_DestAddress = (uint32 *)(LayerPixel + B.LayerBits.ByteOffset * 2); - uint32 *A_DestAddress = (uint32 *)(LayerPixel + B.LayerBits.ByteOffset * 3); - - real32 R_Layer = (real32)(*R_DestAddress & B.LayerBits.MaskPixel) * B.LayerBits.Normalized; - real32 G_Layer = (real32)(*G_DestAddress & B.LayerBits.MaskPixel) * B.LayerBits.Normalized; - real32 B_Layer = (real32)(*B_DestAddress & B.LayerBits.MaskPixel) * B.LayerBits.Normalized; - real32 A_Layer = (real32)(*A_DestAddress & B.LayerBits.MaskPixel) * B.LayerBits.Normalized; - - int32 TrueX = (X - B.LayerBounds.Min.x) - B.ExtraX; - int32 TrueY = (Y - B.LayerBounds.Min.y) - B.ExtraY; - - uint8 *SourcePixel = (uint8 *)B.SourceBuffer + Offset; - Assert(B.SourceBytesPerPixel == 4); - bool32 IsEmpty = (*(uint32 *)SourcePixel == 0x00000000); - if (IsEmpty) - *(uint32 *)SourcePixel = 0x00010101; - - // Assert(TrueX >= 0 && TrueX < BrushLength); - // Assert(TrueY >= 0 && TrueY < BrushLength); - - uint8 *BrushPixel = (uint8 *)B.BrushRow + (TrueY * B.BrushPitch) + (TrueX * B.BytesPerPixel); - - real32 Brush_BitmapAlpha = (real32)((*(uint32 *)(BrushPixel + B.BrushBits.ByteOffset*3)) & B.BrushBits.MaskPixel) * B.BrushBits.Normalized; - - if (!Brush_BitmapAlpha) - continue; - - real32 BrushAlpha = Brush_BitmapAlpha; - real32 LayerAlpha = A_Layer; - - real32 A_Blend = 0; - real32 R_Blend = 0; - real32 G_Blend = 0; - real32 B_Blend = 0; - - if (!B.EraseMode) { - if (IsEmpty) { - R_Blend = B.R_Brush; - G_Blend = B.G_Brush; - B_Blend = B.B_Brush; - A_Blend = LayerAlpha + BrushAlpha; - } else { - R_Blend = B.R_Brush; - G_Blend = B.G_Brush; - B_Blend = B.B_Brush; - A_Blend = LayerAlpha + ((1.0f - LayerAlpha) * BrushAlpha); - real32 Blend = BrushAlpha; - // R_Blend = (R_Layer * (1.0f - Blend)) + (B.R_Brush * Blend); - // G_Blend = (G_Layer * (1.0f - Blend)) + (B.G_Brush * Blend); - // B_Blend = (B_Layer * (1.0f - Blend)) + (B.B_Brush * Blend); - } - // A_Blend = 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); - G_Blend = (G_Brush * (1.0f - LayerAlpha)) + (G_Blend * LayerAlpha); - B_Blend = (B_Brush * (1.0f - LayerAlpha)) + (B_Blend * LayerAlpha); - */ - - Assert(R_Blend <= 1.0f); - - uint32 R_Out = (uint32)(Normalize(R_Blend) * B.LayerBits.Bits); - uint32 G_Out = (uint32)(Normalize(G_Blend) * B.LayerBits.Bits); - uint32 B_Out = (uint32)(Normalize(B_Blend) * B.LayerBits.Bits); - uint32 A_Out = (uint32)(Normalize(A_Blend) * B.LayerBits.Bits); - - *R_DestAddress = (*R_DestAddress & ~B.LayerBits.MaskPixel) | R_Out; - *G_DestAddress = (*G_DestAddress & ~B.LayerBits.MaskPixel) | G_Out; - *B_DestAddress = (*B_DestAddress & ~B.LayerBits.MaskPixel) | B_Out; - *A_DestAddress = (*A_DestAddress & ~B.LayerBits.MaskPixel) | A_Out; - } - } -} - -#if ARM -#else -static void -PaintTest_AVX2(brush_info B, void *Buffer, rectangle RenderRegion) -{ - __m256 One = _mm256_set1_ps(1); - __m256 Zero = _mm256_set1_ps(0); - __m256 Eight = _mm256_set1_ps(8); - __m256i FF = _mm256_set1_epi32(0xFF); - __m256 R_Brush =_mm256_set1_ps(B.R_Brush); - __m256 G_Brush =_mm256_set1_ps(B.G_Brush); - __m256 B_Brush =_mm256_set1_ps(B.B_Brush); - __m256 A_Brush =_mm256_set1_ps(B.A_Brush); - __m256 Norm255 = _mm256_set1_ps(1/255.0f); - __m256 Real255 = _mm256_set1_ps(255.0f); - __m256 LayerBoundsMaxX = _mm256_set1_ps(B.SourceWidth); - - for (int32 Y = RenderRegion.Min.y; Y < RenderRegion.Max.y; Y++) { - __m256 PixelX = _mm256_setr_ps((real32)RenderRegion.Min.x, - (real32)RenderRegion.Min.x+1, - (real32)RenderRegion.Min.x+2, - (real32)RenderRegion.Min.x+3, - (real32)RenderRegion.Min.x+4, - (real32)RenderRegion.Min.x+5, - (real32)RenderRegion.Min.x+6, - (real32)RenderRegion.Min.x+7); - for (int32 X = RenderRegion.Min.x; X < RenderRegion.Max.x; X += 8) { - - __m256i TileBarrier = _mm256_cvtps_epi32(_mm256_cmp_ps(PixelX, LayerBoundsMaxX, 1)); - - uint32 Offset = Y*B.LayerPitch + X*B.SourceBytesPerPixel; - uint8 *LayerPixelAddress = (uint8 *)Buffer + Offset; - - __m256i LayerPixels = _mm256_loadu_si256((const __m256i *)LayerPixelAddress); - - __m256 R_Layer = _mm256_mul_ps(_mm256_cvtepi32_ps(_mm256_and_si256( LayerPixels, FF)), Norm255); - __m256 G_Layer = _mm256_mul_ps(_mm256_cvtepi32_ps(_mm256_and_si256(_mm256_srli_epi32(LayerPixels, 8), FF)), Norm255); - __m256 B_Layer = _mm256_mul_ps(_mm256_cvtepi32_ps(_mm256_and_si256(_mm256_srli_epi32(LayerPixels, 16), FF)), Norm255); - __m256 A_Layer = _mm256_mul_ps(_mm256_cvtepi32_ps(_mm256_and_si256(_mm256_srli_epi32(LayerPixels, 24), FF)), Norm255); - - int32 TrueX = (X - B.LayerBounds.Min.x) - B.ExtraX; - int32 TrueY = (Y - B.LayerBounds.Min.y) - B.ExtraY; - uint8 *BrushPixelAddress = (uint8 *)B.BrushRow + (TrueY * B.BrushPitch) + (TrueX * B.BytesPerPixel); - __m256i BrushPixels = _mm256_loadu_si256((const __m256i *)BrushPixelAddress); - - __m256 Brush_BitmapAlpha = _mm256_mul_ps(_mm256_cvtepi32_ps(_mm256_and_si256(_mm256_srli_epi32(BrushPixels, 24), FF)), Norm255); - - __m256 A_BrushMultiplied = _mm256_mul_ps(Brush_BitmapAlpha, A_Brush); - - __m256 A_Blend = _mm256_add_ps(A_Layer, A_BrushMultiplied); - - __m256 R_Blend = _mm256_add_ps(_mm256_mul_ps(R_Layer, _mm256_sub_ps(One, A_BrushMultiplied)), _mm256_mul_ps(R_Brush, A_BrushMultiplied)); - __m256 G_Blend = _mm256_add_ps(_mm256_mul_ps(G_Layer, _mm256_sub_ps(One, A_BrushMultiplied)), _mm256_mul_ps(G_Brush, A_BrushMultiplied)); - __m256 B_Blend = _mm256_add_ps(_mm256_mul_ps(B_Layer, _mm256_sub_ps(One, A_BrushMultiplied)), _mm256_mul_ps(B_Brush, A_BrushMultiplied)); - - __m256i R_Out = _mm256_cvtps_epi32(_mm256_mul_ps(_mm256_max_ps(_mm256_min_ps(One, R_Blend), Zero), Real255)); - __m256i G_Out = _mm256_cvtps_epi32(_mm256_mul_ps(_mm256_max_ps(_mm256_min_ps(One, G_Blend), Zero), Real255)); - __m256i B_Out = _mm256_cvtps_epi32(_mm256_mul_ps(_mm256_max_ps(_mm256_min_ps(One, B_Blend), Zero), Real255)); - __m256i A_Out = _mm256_cvtps_epi32(_mm256_mul_ps(_mm256_max_ps(_mm256_min_ps(One, A_Blend), Zero), Real255)); - - __m256i OutputPixel = _mm256_or_si256( - _mm256_or_si256(R_Out, _mm256_slli_epi32(G_Out, 8)), - _mm256_or_si256(_mm256_slli_epi32(B_Out, 16), _mm256_slli_epi32(A_Out, 24))); - - // _mm256_storeu_si256((__m256i *)LayerPixelAddress, OutputPixel); - _mm256_maskstore_epi32((int *)LayerPixelAddress, TileBarrier, OutputPixel); - PixelX = _mm256_add_ps(PixelX, Eight); - } - } -} -#endif - -static void -RenderQueue_AddBrush(project_state *State, v2 LayerPos) -{ - State->Queue.Item[State->Queue.CurrentIdx].Pos = LayerPos; - State->Queue.Item[State->Queue.CurrentIdx].Type = 1; - State->Queue.CurrentIdx++; - State->Brush.PrevPos = LayerPos; -} - -static void -RenderQueue_AddBlit(project_state *State) -{ - State->Queue.Item[State->Queue.CurrentIdx].Type = 2; - State->Queue.CurrentIdx++; -} -- cgit v1.2.3