summaryrefslogtreecommitdiff
path: root/createcalls.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'createcalls.cpp')
-rw-r--r--createcalls.cpp1967
1 files changed, 0 insertions, 1967 deletions
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++;
-}