static void InitMemoryTable(global_memory *GlobalMemory, memory *Memory, uint64 Size, memory_table_list TableName, char *Name) { memory_table *Table = &Memory->Slot[TableName]; Table->Name = Name; Table->Address = (uint64 *)((uint8 *)GlobalMemory->Address + GlobalMemory->CurrentPosition); Table->Size = Size; GlobalMemory->CurrentPosition += Size; } static void* AllocateMemory(memory *Memory, uint64 Size, memory_table_list TableName) { void *Address; memory_table *Table = &Memory->Slot[TableName]; if (Table->CurrentPosition + Size > Table->Size) { return NULL; } Address = (uint64 *)((uint8 *)Table->Address + Table->CurrentPosition); Table->CurrentPosition += Size; return Address; } // Returns 0-1 range wherever Pointer is in relation to StartingPointer to Size*Amount. static real32 Memory_NormalizedPosition(void *StartingPointer, uint32 Amount, uint32 Size, void *Pointer) { real32 Result = 0; uint64 TotalSize = Amount*Size; uint64 PointerLocationSize = (uint8 *)Pointer - (uint8 *)StartingPointer; Result = (real32)PointerLocationSize / (real32)TotalSize; return Result; } static void Debug_Memory_Assert_Cohesion(memory *Memory, memory_table *Table) { #if DEBUG for (uint32 i = 0; i < Table->NumberOfPointers; i++) { cached_bitmap *CurrentBitmap = &Memory->Bitmap[i]; Assert(CurrentBitmap->Data); for (uint32 a = 0; a < Table->NumberOfPointers; a++) { if (a == i) { continue; } cached_bitmap *OtherBitmap = &Memory->Bitmap[a]; if (OtherBitmap->Data == CurrentBitmap->Data) { Assert(0); } } } #else #endif } static cached_bitmap * Memory_RollingBitmap(memory *Memory, source *Source, uint32 FrameToSeek) { uint16 Width = Source->Info.Width; uint16 Height = Source->Info.Height; uint16 BytesPerPixel = Source->Info.BytesPerPixel; memory_table *Table = &Memory->Slot[B_LoadedBitmaps]; // First check whether we'd run over the buffer at the current // position, and reset the position if so. uint64 Size = Bitmap_CalcTotalBytes(Width, Height, BytesPerPixel); if (Table->CurrentPosition + Size > Table->Size) { Table->CurrentPosition = 0; Table->PointerIndex = 0; } cached_bitmap *Bitmap = &Memory->Bitmap[Table->PointerIndex]; // If there are no pointers in front of us, we don't have to free any space // and just need to increment the number of pointers. if (Table->PointerIndex != Table->NumberOfPointers) { // Next, if there's a pointer in front of the current position, // check whether it's far away enough so that the size fits. bool32 BS = true; if (Bitmap->Data) { uint64 BytesBetween = (uint8 *)Bitmap->Data - ((uint8 *)Table->Address + Table->CurrentPosition); if (BytesBetween > Size) { uint32 StopAt = Table->NumberOfPointers - 1; while (StopAt > Table->PointerIndex - 1) { Memory->Bitmap[StopAt + 1] = Memory->Bitmap[StopAt]; StopAt--; } Table->NumberOfPointers++; BS = false; } } // If it doesn't fit, then we need to dereference the pointers // until we have enough space. if ((Table->PointerIndex < Table->NumberOfPointers) && BS) { bool32 Avail = false; void *AddressStart = (void *)((uint8 *)Table->Address + Table->CurrentPosition); uint32 Amount = 0; while(!Avail) { // Bail out if we're on the last index, as we don't need to do anything else. // TODO(fox): This could be simplified if we compared // pointer start plus data instead of just the start. if (Table->PointerIndex != Table->NumberOfPointers - 1) { void *Data2 = Memory->Bitmap[Table->PointerIndex+1].Data; uint64 BytesBetween = (uint8 *)Data2 - (uint8 *)AddressStart; if (BytesBetween < Size) { uint32 StopAt = Table->PointerIndex; while (StopAt < Table->NumberOfPointers - 1) { Memory->Bitmap[StopAt] = Memory->Bitmap[StopAt + 1]; StopAt++; } Amount++; Table->NumberOfPointers--; if (Amount > 2) { Amount += 0; } } else { Avail = true; } } else { Avail = true; } } } } else { Table->NumberOfPointers++; } Bitmap->Data = AllocateMemory(Memory, Size, B_LoadedBitmaps); if (!Bitmap->Data) { Assert(0); } Bitmap->SourceOwner = Source; Bitmap->Frame = FrameToSeek; Table->PointerIndex++; // No two pointers on the table should hold the same data // address or be empty. Debug_Memory_Assert_Cohesion(Memory, Table); return Bitmap; }