void PerformTileRelocation() { const int chrBankSize = 0x1000; const int tileSize = 0x10; byte[] CHR = new byte[chrBankSize]; var oBgPatterns = EnhancedPatternOffsets.GetBgBank(levelData.Index); var bankCount = rom.ChrUsage.GetBgLastPage(levelData.Index) - rom.ChrUsage.GetBgFirstPage(levelData.Index) + 1; // Re-arrange CHR ROM for (int i = 0; i < bankCount; i++) { // Copy CHR bank Array.Copy(rom.data, oBgPatterns, CHR, 0, chrBankSize); // Paste new arrangement of tiles into ROM for (int tile = 0; tile < 0x100; tile++) { byte tileIndex = tdArrangement.GetTile(tile); Array.Copy(CHR, tileIndex * 0x10, rom.data, oBgPatterns, tileSize); oBgPatterns += tileSize; } // oBgPatterns now points to next CHR bank } // Re-arrange combos (metatiles) byte[] lookup = tdArrangement.CreateLookupTable(); // Assuming 256 combos for (int i = 0; i < 0x100; i++) { var def = levelData.Combos[i]; def[0] = lookup[def[0]]; def[1] = lookup[def[1]]; def[2] = lookup[def[2]]; def[3] = lookup[def[3]]; } }