0x004613F0
| 695 | |
| 696 | // 0x004613F0 |
| 697 | void defragmentTilePeriodic() |
| 698 | { |
| 699 | if (!Game::hasFlags(GameStateFlags::tileManagerLoaded)) |
| 700 | { |
| 701 | return; |
| 702 | } |
| 703 | if (_disablePeriodicDefrag) |
| 704 | { |
| 705 | _disablePeriodicDefrag = false; |
| 706 | return; |
| 707 | } |
| 708 | _disablePeriodicDefrag = false; |
| 709 | |
| 710 | const uint32_t searchStart = _periodicDefragStartTile + 1; |
| 711 | for (auto i = 0U; i < kNumTiles; ++i) |
| 712 | { |
| 713 | const auto j = (i + searchStart) % kNumTiles; |
| 714 | if (_tiles[j] != nullptr) |
| 715 | { |
| 716 | _periodicDefragStartTile = j; |
| 717 | break; |
| 718 | } |
| 719 | } |
| 720 | |
| 721 | auto* firstTile = _tiles[_periodicDefragStartTile]; |
| 722 | auto* emptyTile = firstTile - 1; |
| 723 | while (emptyTile != &_elements[0] && emptyTile->baseZ() == 0xFFU) |
| 724 | { |
| 725 | emptyTile--; |
| 726 | } |
| 727 | emptyTile++; |
| 728 | if (emptyTile == firstTile) |
| 729 | { |
| 730 | return; |
| 731 | } |
| 732 | |
| 733 | _tiles[_periodicDefragStartTile] = emptyTile; |
| 734 | { |
| 735 | auto* dest = emptyTile; |
| 736 | auto* source = firstTile; |
| 737 | do |
| 738 | { |
| 739 | *dest = *source; |
| 740 | source->setBaseZ(0xFFU); |
| 741 | source++; |
| 742 | } while (!dest++->isLast()); |
| 743 | } |
| 744 | |
| 745 | // Its possible we have freed up elements at the end so this |
| 746 | // looks to see if we should move the element end |
| 747 | auto newEnd = _elementsEnd - 1; |
| 748 | while (_elements[newEnd].baseZ() == 0xFFU) |
| 749 | { |
| 750 | newEnd--; |
| 751 | } |
| 752 | _elementsEnd = newEnd + 1; |
| 753 | } |
| 754 |