summaryrefslogtreecommitdiff
path: root/undo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'undo.cpp')
-rw-r--r--undo.cpp308
1 files changed, 0 insertions, 308 deletions
diff --git a/undo.cpp b/undo.cpp
deleted file mode 100644
index bfedc8c..0000000
--- a/undo.cpp
+++ /dev/null
@@ -1,308 +0,0 @@
-struct history_info {
- uint16 ActionCount_Total;
- uint16 ActionCount_EndOfPlayhead;
- uint16 ActionCount_Current;
-
- uint64 ActionOffset_Total;
- uint64 ActionOffset_EndOfPlayhead;
- uint64 ActionOffset_Current;
-
- uint64 EntrySize_Current;
-};
-
-static uint64
-History_GetActionSize(history_entry_list *History, int i, uint16 ActionCount_EndOfPlayhead)
-{
- history_action *Action = &History->Action[i];
- if (Action->Type == action_type_swap || Action->Type == action_type_swap_bitmap)
- return Action->Size;
- return 0;
-}
-
-// Returns information on the undo tree based on three points of data: the
-// total amount of entries, the location of the playhead, and whatever location
-// SampleIndex is set to, which should be either one minus playhead or the playhead.
-
-// I wrote this with the intent of precomputing things like the tree's total
-// size and the size of the current action, because calculating them in the
-// Action_Redo/Undo calls got extremely confusing.
-
-static history_info
-History_GetTreeInfo(history_entry_list *History, uint16 SampleIndex)
-{
- history_info Info = {};
-
- for (int i = 0; i < History->NumberOfEntries; i++)
- {
- history_entry *Entry = &History->Entry[i];
- Info.ActionCount_Total += Entry->NumberOfActions;
- if (i < History->EntryPlayhead)
- Info.ActionCount_EndOfPlayhead += Entry->NumberOfActions;
- if (i < SampleIndex)
- Info.ActionCount_Current += Entry->NumberOfActions;
- }
-
- for (int i = 0; i < Info.ActionCount_Total; i++)
- {
- uint64 Size = History_GetActionSize(History, i, Info.ActionCount_EndOfPlayhead);
- Info.ActionOffset_Total += Size;
- if (i < Info.ActionCount_EndOfPlayhead)
- Info.ActionOffset_EndOfPlayhead += Size;
-
- if (i < Info.ActionCount_Current)
- Info.ActionOffset_Current += Size;
- else if (i < Info.ActionCount_EndOfPlayhead) // Only increment the current size if i is between
- Info.EntrySize_Current += Size; // the current count and playhead count!
- }
-
- return Info;
-}
-
-// This function works exactly the same whether we're in undo/redo, pretty neat.
-void History_Action_DoSwapBitmap(memory *Memory, history_action *ActionPointer, uint8 *Address_HistoryTree_Start, uint8 *Address_HistoryTree_End, uint8 *Address_Data)
-{
- history_action Action = *ActionPointer;
-
- uint64 FullSize = Action.ShiftAmount;
- uint64 CompressedSize = Action.Size;
-
- uint32 BytesForCompressedPart = (uint32)100 * 1024 * 1024;
- void *UncompressedTempBuffer = Memory_PushScratch(Memory, FullSize);
- void *CompressedTempBuffer = Memory_PushScratch(Memory, BytesForCompressedPart);
-
- // First we decompress and swap the saved pixels with the newer ones...
- Data_Decompress(Memory, Address_HistoryTree_Start, CompressedSize, UncompressedTempBuffer, FullSize);
- Bitmap_SwapData((uint8 *)UncompressedTempBuffer, (uint8 *)Address_Data, FullSize, Action.Direction);
-
- // Then we recompress the old pixels and evaluate its size, and since the size can be different...
- uint64 NewSize = Data_Compress(Memory, UncompressedTempBuffer, FullSize, CompressedTempBuffer, BytesForCompressedPart, Z_BEST_SPEED);
-
- // we have to shift the undo stack.
- if (NewSize != CompressedSize) {
- int16 ShiftDirection = (NewSize > CompressedSize) ? 1 : -1;
- uint64 ShiftAmount = (NewSize > CompressedSize) ? NewSize - CompressedSize : CompressedSize - NewSize;
- Arbitrary_ShiftData(Address_HistoryTree_Start + CompressedSize, Address_HistoryTree_End, ShiftAmount, ShiftDirection);
- }
- Memory_Copy(Address_HistoryTree_Start, (uint8 *)CompressedTempBuffer, NewSize);
-
- ActionPointer->Size = NewSize;
- Memory_PopScratch(Memory, BytesForCompressedPart);
- Memory_PopScratch(Memory, FullSize);
-}
-
-void History_Action_Undo(memory *Memory, history_info Info, history_action *ActionPointer, uint64 Action_Offset)
-{
- history_entry_list *History = &Memory->History;
-
- // Only swap_bitmap should touch the data!
- history_action Action = *ActionPointer;
-
- uint8 *Address_HistoryTree_Start = (uint8 *)Memory_AddressAtOffset(Memory, P_UndoBuffer, Action_Offset);
- uint8 *Address_HistoryTree_End = (uint8 *)Memory_AddressAtOffset(Memory, P_UndoBuffer, Info.ActionOffset_Total);
- uint8 *Address_Data = (uint8 *)Memory_AddressAtOffset(Memory, Action.TableName, Action.ByteOffset);
-
- if (Action.Type == action_type_swap) {
- Arbitrary_SwapData(Memory, Address_HistoryTree_Start, Address_Data, Action.Size);
- } else if (Action.Type == action_type_swap_bitmap) {
- History_Action_DoSwapBitmap(Memory, ActionPointer, Address_HistoryTree_Start, Address_HistoryTree_End, Address_Data);
- } else if (Action.Type == action_type_shift) {
- // In order to shift back we have to start the address at where the
- // shifted chunk is _now_, not when we called the function.
- uint64 NewByteOffset = (Action.Direction > 0) ? Action.ByteOffset + Action.ShiftAmount : Action.ByteOffset - Action.ShiftAmount;
- void *Address_Start = Memory_AddressAtOffset(Memory, Action.TableName, NewByteOffset);
- uint8 *Address_End = (uint8 *)Address_Start + Action.Size;
- // Direction also needs to be reversed.
- int16 Direction = Action.Direction * -1;
- Arbitrary_ShiftData((uint8 *)Address_Start, Address_End, Action.ShiftAmount, Direction);
- } else {
- Assert(0);
- }
-}
-
-void History_Action_Redo(memory *Memory, history_info Info, history_action *ActionPointer, uint64 Action_Offset) {
-
- history_entry_list *History = &Memory->History;
-
- history_action Action = *ActionPointer;
-
- uint8 *Address_HistoryTree_Start = (uint8 *)Memory_AddressAtOffset(Memory, P_UndoBuffer, Action_Offset);
- uint8 *Address_HistoryTree_End = (uint8 *)Memory_AddressAtOffset(Memory, P_UndoBuffer, Info.ActionOffset_Total);
- uint8 *Address_Data = (uint8 *)Memory_AddressAtOffset(Memory, Action.TableName, Action.ByteOffset);
-
- if (Action.Type == action_type_swap) {
- Arbitrary_SwapData(Memory, Address_HistoryTree_Start, Address_Data, Action.Size);
- } else if (Action.Type == action_type_swap_bitmap) {
- History_Action_DoSwapBitmap(Memory, ActionPointer, Address_HistoryTree_Start, Address_HistoryTree_End, Address_Data);
- } else if (Action.Type == action_type_shift) {
- void *Address_Start = Memory_AddressAtOffset(Memory, Action.TableName, Action.ByteOffset);
- uint8 *Address_End = (uint8 *)Address_Start + Action.Size;
- int16 Direction = Action.Direction;
- Arbitrary_ShiftData((uint8 *)Address_Start, Address_End, Action.ShiftAmount, Direction);
- } else {
- Assert(0);
- }
-}
-
-void History_Undo(memory *Memory) {
- history_entry_list *History = &Memory->History;
- if (History->EntryPlayhead == 0) return;
-
- // We want Current to represent the beginning of the current entry, so we
- // subtract one from the playhead.
- history_info Info = History_GetTreeInfo(History, History->EntryPlayhead - 1);
- history_entry *Entry = &History->Entry[History->EntryPlayhead - 1];
-
- // This puts us at the end of the current entry's offset.
- uint64 ActionOffset_Stepback = Info.ActionOffset_Current + Info.EntrySize_Current;
-
- for (int i = Entry->NumberOfActions - 1; i >= 0; i--) {
- history_action *Action = &History->Action[Info.ActionCount_Current + i];
-
- // We step backwards only if the action is currently storing data.
- if (Action->Type != action_type_shift)
- ActionOffset_Stepback -= Action->Size;
-
- History_Action_Undo(Memory, Info, Action, ActionOffset_Stepback);
- }
-
- History->EntryPlayhead--;
-
-}
-
-void History_Redo(memory *Memory) {
- history_entry_list *History = &Memory->History;
- if (History->EntryPlayhead == History->NumberOfEntries) return;
-
- // NOTE(fox): The third part of this function for recording the "current"
- // action's size is only necessary for the undo call, so it's not correct on the redo.
- history_info Info = History_GetTreeInfo(History, History->EntryPlayhead);
- history_entry *Entry = &History->Entry[History->EntryPlayhead];
-
- History->EntryPlayhead++;
-
- uint64 ActionOffset_Stepforward = Info.ActionOffset_Current;
-
- for (int i = 0; i < Entry->NumberOfActions; i++) {
- history_action *Action = &History->Action[Info.ActionCount_Current + i];
-
- History_Action_Redo(Memory, Info, Action, ActionOffset_Stepforward);
-
- // We step forwards only if the action is currently storing data.
- if (Action->Type != action_type_shift)
- ActionOffset_Stepforward += Action->Size;
-
- }
-
-}
-
-// This is only called when we're certain the action is going to be taken.
-void History_Entry_Commit(memory *Memory, char *Name)
-{
- history_entry_list *History = &Memory->History;
- history_entry *Entry = &History->Entry[History->EntryPlayhead];
- Entry->Name = Name;
- Entry->NumberOfActions = 0;
- // Effectively deletes entries in front if we're beginning out of an undo.
- if (History->NumberOfEntries != History->EntryPlayhead)
- History->NumberOfEntries = History->EntryPlayhead;
- History->NumberOfEntries++;
- History->EntryPlayhead++;
- Memory->IsFileSaved = false;
-#if DEBUG
- Assert(Debug.UndoState != 1); // You forgot to end a History_Entry_Commit()!
- Debug.UndoState = 1;
-#endif
-}
-
-void History_Entry_End(memory *Memory)
-{
- history_entry_list *History = &Memory->History;
-#if DEBUG
- Debug.UndoState = 0;
-#endif
-}
-
-// NOTE(fox): Shift is the only action that additionally changes the data after
-// the info is put on the tree, since it's always the same function used.
-
-static void History_Action_Add(memory *Memory, history_action ActionData, void *ReferenceData = NULL)
-{
- history_entry_list *History = &Memory->History;
- history_entry *Entry = &History->Entry[History->EntryPlayhead - 1];
-
- history_info Info = History_GetTreeInfo(History, History->EntryPlayhead - 1);
-
- history_action *Action = &History->Action[Info.ActionCount_Total];
- *Action = ActionData;
-
- if (Action->Type == action_type_swap)
- {
- void *Address_HistoryTree = Memory_AddressAtOffset(Memory, P_UndoBuffer, Info.ActionOffset_Total);
- void *Address_Data = Memory_AddressAtOffset(Memory, Action->TableName, Action->ByteOffset);
- Memory_Copy((uint8 *)Address_HistoryTree, (uint8 *)Address_Data, Action->Size);
- } else if (Action->Type == action_type_swap_bitmap)
- {
- // The address of data to be stored in the undo tree is not the same as
- // the address to be recorded, so we have to pass it manually.
- void *Address_HistoryTree = Memory_AddressAtOffset(Memory, P_UndoBuffer, Info.ActionOffset_Total);
- void *Address_Data = ReferenceData;
-
- // Libz/miniz requires passing an amount of available space, and it
- // returns how much space the compressed data actually is.
- // We don't need to alloc any more memory since we can just use the
- // history tree as the destination.
- // ShiftAmount is also being used to save the uncompressed size.
- uint32 BytesForCompressedPart = (uint32)100 * 1024 * 1024;
- Action->Size = Data_Compress(Memory, Address_Data, Action->ShiftAmount, Address_HistoryTree, BytesForCompressedPart, Z_BEST_SPEED);
-
- } else if (Action->Type == action_type_shift)
- {
- void *Address_Start = Memory_AddressAtOffset(Memory, Action->TableName, Action->ByteOffset);
- uint8 *Address_End = (uint8 *)Address_Start + Action->Size;
- Arbitrary_ShiftData((uint8 *)Address_Start, Address_End, Action->ShiftAmount, Action->Direction);
- }
-
- Entry->NumberOfActions++;
-}
-
-// Helper functions for different tables.
-
-static void History_Action_BitmapPaint(memory *Memory, uint64 Size_Uncompressed,
- void *SourceBitmapAddress, void *CachedPaintAddress, int16 BytesPerPixel)
-{
- void *Address_Start = Memory->Slot[F_PrincipalBitmaps].Address;
- uint64 ByteOffset = (ptrsize)SourceBitmapAddress - (ptrsize)Address_Start;
- history_action Action = { F_PrincipalBitmaps, action_type_swap_bitmap, 0, ByteOffset, Size_Uncompressed, BytesPerPixel };
- History_Action_Add(Memory, Action, CachedPaintAddress);
-}
-
-static void History_Action_Shift(memory *Memory, memory_table_list TableName,
- void *Address0, void *Address1, uint64 Amount, int16 Direction)
-{
- void *Address_Start = Memory->Slot[TableName].Address;
- uint64 ByteOffset = (ptrsize)Address0 - (ptrsize)Address_Start;
- uint64 Size = (ptrsize)Address1 - (ptrsize)Address0;
-
- history_action Action = { TableName, action_type_shift, Size, ByteOffset, Amount, Direction };
-
- History_Action_Add(Memory, Action);
-}
-
-static void History_Action_Block_Swap(memory *Memory, memory_table_list TableName, void *Address_Data)
-{
- void *Address_Start = Memory->Slot[TableName].Address;
- uint64 Size = Memory->Slot[TableName].Block_ElementSize;
- uint64 ByteOffset = (ptrsize)Address_Data - (ptrsize)Address_Start;
- history_action Action = { TableName, action_type_swap, Size, ByteOffset, 0 };
- History_Action_Add(Memory, Action);
-}
-
-// Remember to dereference pointers if taking the sizeof() a variable, or else Size will be 8!
-
-static void History_Action_Swap(memory *Memory, memory_table_list TableName, uint64 Size, void *Address_Data)
-{
- void *Address_Start = Memory->Slot[TableName].Address;
- uint64 ByteOffset = (ptrsize)Address_Data - (ptrsize)Address_Start;
- history_action Action = { TableName, action_type_swap, Size, ByteOffset, 0 };
- History_Action_Add(Memory, Action);
-}