void TailsAdvBank0Hacks::addRegularInventoryHotswapHack( WritableROM& rom) { // Write hotswap hack rom.directWrite(regularInventoryHotswapHackMainAddress, regularInventoryHotswapHackMainData, regularInventoryHotswapHackMainLength); // Write hotswap trigger rom.directWrite(regularInventoryHotswapHackTriggerAddress, regularInventoryHotswapHackTriggerData, regularInventoryHotswapHackTriggerLength); }
void TailsAdvBank0Hacks::addFullInventoryHotswapHack( WritableROM& rom) { // Use full inventory addUseAllInventoryHack(rom); // Write hotswap hack rom.directWrite(fullInventoryHotswapHackMainAddress, fullInventoryHotswapHackMainData, fullInventoryHotswapHackMainLength); // Write hotswap trigger rom.directWrite(fullInventoryHotswapHackTriggerAddress, fullInventoryHotswapHackTriggerData, fullInventoryHotswapHackTriggerLength); }
void TailsAdvBank0Hacks::addAutoSaveHack( WritableROM& rom) { addSaveHackBase(rom); rom.directWrite(autoSaveHackAddress, autoSaveHackData, autoSaveHackLength); }
void EditableSpawnPoints::exportElementToROM(WritableROM& rom, Taddress address, SpawnPointCollection& src) { Taddress writeAddress = address; for (SpawnPointCollection::iterator it = src.begin(); it != src.end(); ++it) { // std::cout << writeAddress << std::endl; // std::cout << '\t' << it->camX() << std::endl; // Buffer for data Tbyte dataBuffer[SpawnPoint::dataSize]; // Write spawn to data it->writeToData(dataBuffer); // for (int i = 0; i < SpawnPoint::dataSize; i++) { // std::cout << (int)(dataBuffer[i]) << " "; // } // std::cout << std::endl; // Copy raw spawn data to ROM rom.directWrite(writeAddress, dataBuffer, SpawnPoint::dataSize); // Advance to next address writeAddress += SpawnPoint::dataSize; } }
void TailsAdvBank0Hacks::addStartingItemHack( WritableROM& rom, Tbyte startingItemID, Tbyte sfStartingItemID, bool allItemsEnabled) { rom.directWrite(startingItemHackItemIDAddress, &startingItemID, ByteSizes::uint8Size); StartingItemHackUnlockPair unlockPair = startingItemHackItemUnlockLocations[startingItemID]; StartingItemHackUnlockPair sfUnlockPair = startingItemHackItemUnlockLocations[sfStartingItemID]; ByteConversion::toBytes(unlockPair.address, rom.directWrite( startingItemHackUnlockLocationAddress), ByteSizes::uint16Size, EndiannessTypes::little, SignednessTypes::nosign); ByteConversion::toBytes(bitNumToHLIndirectOpcodeParam( unlockPair.bit), rom.directWrite( startingItemHackUnlockBitAddress), ByteSizes::uint8Size, EndiannessTypes::little, SignednessTypes::nosign); ByteConversion::toBytes(sfUnlockPair.address, rom.directWrite( startingItemHackSFUnlockLocationAddress), ByteSizes::uint16Size, EndiannessTypes::little, SignednessTypes::nosign); ByteConversion::toBytes(bitNumToHLIndirectOpcodeParam( sfUnlockPair.bit), rom.directWrite( startingItemHackSFUnlockBitAddress), ByteSizes::uint8Size, EndiannessTypes::little, SignednessTypes::nosign); if (allItemsEnabled) { Tbyte pos = startingItemHackItemToPos[startingItemID]; Tbyte sfPos = startingItemHackItemToPos[sfStartingItemID]; rom.directWrite(startingItemHackAllItemsPosAddress, &pos, ByteSizes::uint8Size); rom.directWrite(startingItemHackAllItemsSFPosAddress, &sfPos, ByteSizes::uint8Size); rom.directWrite(startingItemHackAllItemsSFSlotAddress, &sfStartingItemID, ByteSizes::uint8Size); } }
void TailsAdvBank0Hacks::addSaveHackBase( WritableROM& rom) { rom.directWrite(saveHackAddress1, saveHackData1, saveHackLength1); rom.directWrite(saveHackAddress2, saveHackData2, saveHackLength2); rom.directWrite(saveHackAddress3, saveHackData3, saveHackLength3); rom.directWrite(saveHackAddress4, saveHackData4, saveHackLength4); }
void EditablePowerUpData::exportToROM(WritableROM& rom) { int byteCount = 0; for (int i = 0; i < numPowerUps_; i++) { ByteConversion::toBytes(MiscMath::toBCD(maxHealthPerPowerup_[i]), rom.directWrite(powerUpTableAddress_ + byteCount), ByteSizes::uint8Size, EndiannessTypes::little, SignednessTypes::nosign); byteCount += ByteSizes::uint8Size; ByteConversion::toBytes(flightTimePerPowerup_[i], rom.directWrite(powerUpTableAddress_ + byteCount), ByteSizes::uint16Size, EndiannessTypes::little, SignednessTypes::nosign); byteCount += ByteSizes::uint16Size; } }
void TailsAdvData::exportToROM(WritableROM& rom) { /* A VERY LONG SEQUENCE OF EXPORTS GOES HERE */ if (romExpanded_) { // If the ROM has been expanded, there are now 0x40 rather than 0x20 // valid banks. However, there are a handful of pieces of code that // mask a value by 0x1F to obtain a bank number. We need to adjust these // to 0x3F or the program will be unable to access the new banks. rom.directWrite(andMaskExpandAdjustAddress1, andMaskExpandAdjustValue, ByteSizes::uint8Size); rom.directWrite(andMaskExpandAdjustAddress2, andMaskExpandAdjustValue, ByteSizes::uint8Size); } standardPalettes_.exportToROM(rom); paletteCycles_.exportToROM(rom); levelEffectsHeaders_.exportToROM(rom); levelPaletteHeaders_.exportToROM(rom); levelGraphicsData_.exportToROM(rom); tileMaps_.exportToROM(rom); leafGraphicsTable_.exportToROM(rom); waterSplashGraphicTable_.exportToROM(rom); smokePuffGraphicTable_.exportToROM(rom); spriteMappings_.exportToROM(rom); musicAssignments_.exportToROM(rom); radioMusic_.exportToROM(rom); powerUpData_.exportToROM(rom); emeraldHealthRefills_.exportToROM(rom); metatileWidthMaps_.exportToROM(rom); metatileHeightMaps_.exportToROM(rom); slopeSpeedValues_.exportToROM(rom); metatileBehaviors_.exportToROM(rom); spawnPoints_.exportToROM(rom); warpDestinations_.exportToROM(rom); levelObjectEntryGroups_.exportToROM(rom); mapData_.exportToROM(rom); }
void TailsAdvBank0Hacks::addDoubleJumpFixHack( WritableROM& rom) { // Copy the original jump height Tbyte jHeight[1]; std::memcpy(jHeight, rom.directRead(doubleJumpFixHackJumpHeightAddress), 1); // Decrement jump height by 1 for hack jHeight[0] = (jHeight[0] - 1); // Write fix to ROM rom.directWrite(doubleJumpFixHackAddress, doubleJumpFixHackData, doubleJumpFixHackLength); // Copy jump height + 1 rom.directWrite(doubleJumpFixHackAddress + doubleJumpFixHackJumpHeightOffset, jHeight, 1); }
void TailsAdvBank0Hacks::addFlightLimiterHack( WritableROM& rom) { rom.directWrite(flightLimiterHackMain1Address, flightLimiterHackMain1Data, flightLimiterHackMain1Length); rom.directWrite(flightLimiterHackMain2Address, flightLimiterHackMain2Data, flightLimiterHackMain2Length); rom.directWrite(flightLimiterHackTrigger1Address, flightLimiterHackTrigger1Data, flightLimiterHackTrigger1Length); rom.directWrite(flightLimiterHackTrigger2Address, flightLimiterHackTrigger2Data, flightLimiterHackTrigger2Length); rom.directWrite(flightLimiterHackTrigger3Address, flightLimiterHackTrigger3Data, flightLimiterHackTrigger3Length); }
void EditableLevelPaletteHeaders::exportToROM(WritableROM& rom) { // Write palette headers int contentWriteAddress = tableContentAddress_; for (LevelPaletteHeaderCollection::iterator it = primaryStorage_.begin(); it != primaryStorage_.end(); it++) { it->exportToROM(rom, contentWriteAddress); contentWriteAddress += LevelPaletteHeader::dataSize; } // Write table header int headerWriteAddress = tableHeaderAddress_; // std::cout << "start: " << std::hex << headerWriteAddress << std::endl; for (int i = 0; i < mapnumToIndex_.numPrimaryKeys(); i++) { // std::cout << "at: " << std::hex << headerWriteAddress << std::endl; // Only write used keys if (mapnumToIndex_.subKeyTable()[i] > 0) { // std::cout << '\t' << "writing " << std::hex << i << std::endl; int index = mapnumToIndex_.refDataByKeys( i, TwoKeyedAddress::subKeyBase); // std::cout << '\t' << "index: " << index << std::endl; // Get banked address of content Taddress address = LoadedROM::indexToBankedAddr(tableContentAddress_, index, LevelPaletteHeader::dataSize); Tbyte buffer[ByteSizes::uint16Size]; ByteConversion::toBytes(address, buffer, ByteSizes::uint16Size, EndiannessTypes::little, SignednessTypes::nosign); // std::cout << "number: " << std::hex << i << std::endl; // std::cout << "write address: " << std::hex << headerWriteAddress << std::endl; // Write address to ROM rom.directWrite(headerWriteAddress, buffer, ByteSizes::uint16Size); } // Go to next address headerWriteAddress += ByteSizes::uint16Size; } }
void TailsAdvBank0Hacks::addStartOnLevelHack( WritableROM& rom, Tbyte area, Tbyte map, Tbyte spawn) { rom.directWrite(startOnLevelHackAddress1, startOnLevelHackData1, startOnLevelHackLength1); // Fill in area, map, spawn num rom.directWrite(startOnLevelHackAddress1 + startOnLevelHackData1AreaOffset, &area, ByteSizes::uint8Size); rom.directWrite(startOnLevelHackAddress1 + startOnLevelHackData1MapOffset, &map, ByteSizes::uint8Size); rom.directWrite(startOnLevelHackAddress1 + startOnLevelHackData1SpawnOffset, &spawn, ByteSizes::uint8Size); rom.directWrite(startOnLevelHackAddress2, startOnLevelHackData2, startOnLevelHackLength2); // Copy and shift block Tbyte copyTemp[startOnLevelHackCopyLength]; std::memcpy(copyTemp, rom.directRead(startOnLevelHackCopySrcAddress), startOnLevelHackCopyLength); std::memcpy(rom.directWrite(startOnLevelHackCopyDstAddress), copyTemp, startOnLevelHackCopyLength); // Fill in data rom.directWrite(startOnLevelHackAddress3, startOnLevelHackData3, startOnLevelHackLength3); rom.directWrite(startOnLevelHackAddress4, startOnLevelHackData4, startOnLevelHackLength4); }
void EditableSlopeSpeedValues::exportToROM(WritableROM& rom) { // Write each value to ROM int writeAddress = baseAddress_; for (SlopeSpeedValueCollection::iterator it = speedValues_.begin(); it != speedValues_.end(); ++it) { Tbyte buffer[ByteSizes::int16Size]; ByteConversion::toBytes(*it, buffer, ByteSizes::int16Size, EndiannessTypes::little, SignednessTypes::sign); rom.directWrite(writeAddress, buffer, ByteSizes::int16Size); writeAddress += ByteSizes::int16Size; } }
void MetatileStructureSet::exportToROM(WritableROM& rom) { // TODO: support for adding metatile definitions // search freespace &c FreeSpaceList::iterator spaceIt = rom.freeSpace().getFreeSpace( exportSize()); if (spaceIt == rom.freeSpace().freeSpaceList().end()) { throw NotEnoughSpaceException(TALES_SRCANDLINE, "MetatileStructureSet::exportToROM(" "WritableROM&)", exportSize()); } int writeAddress = spaceIt->address(); address_ = spaceIt->address(); rom.freeSpace().claimSpace(spaceIt, exportSize()); // std::cout << "addr: " << writeAddress << std::endl; // Starting address of structure definitions int contentStartAddress = writeAddress + (index_.size() * ByteSizes::uint16Size); // Write the index for (MetatileIndexToStructureMap::iterator it = index_.begin(); it != index_.end(); it++) { int contentIndex = it->second; // Compute the address of the content Taddress contentAddress = (contentStartAddress + (contentIndex * MetatileStructure::dataSize)); // Convert to banked address Taddress contentBankedAddress = LoadedROM ::directToBankedAddress(contentAddress); // Write to index Tbyte buffer[ByteSizes::uint16Size]; ByteConversion::toBytes(contentBankedAddress, buffer, ByteSizes::uint16Size, EndiannessTypes::little, SignednessTypes::nosign); rom.directWrite(writeAddress + (it->first * ByteSizes::uint16Size), buffer, ByteSizes::uint16Size); } // Write content int metatileNum = 0; for (MetatileStructureCollection::iterator it = primaryStorage_.begin(); it != primaryStorage_.end(); it++) { // Write metatile to buffer Tbyte buffer[MetatileStructure::dataSize]; it->writeToData(buffer); // Write buffer to table rom.directWrite(contentStartAddress + (metatileNum * MetatileStructure::dataSize), buffer, MetatileStructure::dataSize); ++metatileNum; } // std::cout << "metatiles: " << metatileNum << std::endl; // std::cout << std::endl; }
void TailsAdvBank0Hacks::addBombWhileJumpingGraphicFixHack( WritableROM& rom) { rom.directWrite(bombWhileJumpingGraphicFixAddress, bombWhileJumpingGraphicFixData, bombWhileJumpingGraphicFixLength); }
void EditableLevelObjectEntryGroups::exportTable( Taddress exportAddress, WritableROM& rom) { // std::cout << "Exporting to: " << exportAddress << std::endl; // Subkey address write location Taddress subkeyWriteAddress = exportAddress + (primaryMapLimit * ByteSizes::uint16Size); // std::cout << std::hex << subkeyWriteAddress << std::endl; // Determine total number of maps to output int numSubkeyEntries = 0; for (int i = 0; i < mapnumToAddress_.numPrimaryKeys(); i++) { // If at least one entry for this primary key, use first entry if (mapnumToAddress_.subKeyTable()[i] > 0) { numSubkeyEntries += mapnumToAddress_.subKeyTable()[i]; } } // Compute base address for entries Taddress entryWriteAddress = subkeyWriteAddress + (numSubkeyEntries * ByteSizes::uint16Size); // Temporarily convert address table to index table for (int i = 0; i < mapnumToAddress_.numPrimaryKeys(); i++) { for (int j = 0; j < mapnumToAddress_.subKeyTable()[i]; j++) { Taddress& addr = mapnumToAddress_.refDataByKeys( i + TwoKeyedAddress::primaryKeyBase, j + TwoKeyedAddress::subKeyBase); int ind = addressToIndex_.findValueOrThrow(addr); addr = ind; } } // Clear address to index map addressToIndex_.clear(); // Create temporary mapping of indices to address Tmap<int, Taddress> indToAddr; for (int i = 0; i < primaryStorage_.size(); i++) { // Add new (temporary) index->address mapping indToAddr.insert(Tmap<int, Taddress>::PairType( i, entryWriteAddress)); // Write entry to ROM int writeLength = primaryStorage_[i].writeToData( rom.directWrite(entryWriteAddress)); // Add new address->index mapping addressToIndex_.insert( BaseEditableMappedData<LevelObjectEntryGroup> ::AddressIndexPair( entryWriteAddress, i)); // Write subkey address /* Taddress bankedAddress = LoadedROM::directToBankedAddress( entryWriteAddress); ByteConversion::toBytes(bankedAddress, rom.directWrite(subkeyWriteAddress), ByteSizes::uint16Size, EndiannessTypes::little, SignednessTypes::nosign); // std::cout << std::hex << "value: " << bankedAddress << std::endl; // std::cout << std::hex << "addr: " << subkeyWriteAddress << std::endl; // Move to next address subkeyWriteAddress += ByteSizes::uint16Size; */ entryWriteAddress += writeLength; } // Write the address table to the export location Taddress primaryWriteAddress = exportAddress; int totalMaps = 0; for (int i = 0; i < mapnumToAddress_.numPrimaryKeys(); i++) { Taddress bankedAddress = exportAddress + (primaryMapLimit * ByteSizes::uint16Size); // If at least one entry for this primary key, use first entry if (mapnumToAddress_.subKeyTable()[i] > 0) { bankedAddress += (totalMaps * ByteSizes::uint16Size); totalMaps += mapnumToAddress_.subKeyTable()[i]; /* bankedAddress = indToAddr.findValueOrThrow( mapnumToAddress_.refDataByKeys( i + TwoKeyedAddress::primaryKeyBase, TwoKeyedAddress::subKeyBase)); */ } bankedAddress = LoadedROM::directToBankedAddress(bankedAddress); // Write primary address ByteConversion::toBytes(bankedAddress, rom.directWrite(primaryWriteAddress), ByteSizes::uint16Size, EndiannessTypes::little, SignednessTypes::nosign); primaryWriteAddress += ByteSizes::uint16Size; // Convert indices back to addresses for (int j = 0; j < mapnumToAddress_.subKeyTable()[i]; j++) { Taddress& ind = mapnumToAddress_.refDataByKeys( i + TwoKeyedAddress::primaryKeyBase, j + TwoKeyedAddress::subKeyBase); // std::cout << ind << std::endl; // Get address corresponding to this index Taddress address = indToAddr.findValueOrThrow(ind); // std::cout << address << std::endl; // Write subkey address Taddress bankedSubAddress = LoadedROM::directToBankedAddress( address); ByteConversion::toBytes(bankedSubAddress, rom.directWrite(subkeyWriteAddress), ByteSizes::uint16Size, EndiannessTypes::little, SignednessTypes::nosign); // Move to next address subkeyWriteAddress += ByteSizes::uint16Size; // Convert indexed address table back to address table ind = address; } } // Export each data element to ROM /* for (typename AddressIndexMap::iterator it = addressToIndex_.begin(); it != addressToIndex_.end(); it++) { // Address to write to Taddress address = it->first; // Write data exportElementToROM(rom, address, primaryStorage_[it->second]); } */ }
void EditableLevelObjectEntryGroups::exportElementToROM(WritableROM& rom, Taddress address, LevelObjectEntryGroup& src) { src.writeToData(rom.directWrite(address)); }
Taddress EditableLevelObjectEntryGroups::moveToNewBank(WritableROM& rom) { // std::cout << "Preparing to move to new bank" << std::endl; // More for convenience than anything else, we grab a whole bank of data // for use by this table (and a few bits of associated code). // Note that this basically requires expanding the ROM to 1 MB FreeSpaceList::iterator spaceIt = rom.freeSpace().getFreeSpace(LoadedROM::bankSize); // Throw if a full bank isn't available if (spaceIt == rom.freeSpace().freeSpaceList().end()) { throw NotEnoughSpaceException(TALES_SRCANDLINE, "EditableLevelObjectEntryGroups::" "exportToROM(WritableROM&)", LoadedROM::bankSize); } // std::cout << spaceIt->address() << " " << spaceIt->length() << std::endl; Taddress newBaseAddress = spaceIt->address(); // Claim the bank rom.freeSpace().claimSpace(spaceIt, LoadedROM::bankSize); // std::cout << "New base address: " << newBaseAddress << std::endl; // Copy code segments C1 and C3 to new bank. // C1 and C3 both contain code that references the object table, // so they must (to avoid more complicated hacking) be in the same bank. // After rearranging the code, the new bank will contain C1, C3, and // the object table, in that order, starting from the beginning of the // bank // Copy C1 to start of bank Taddress newC1Address = newBaseAddress; std::memcpy(rom.directWrite(newC1Address), codeSegmentC1, lengthOfC1Segment); // Copy C3 to directly after C1 Taddress newC3Address = newC1Address + lengthOfC1Segment; std::memcpy(rom.directWrite(newC3Address), codeSegmentC3, lengthOfC3Segment); // Set new export address for table (directly after C3) int exportAddress = newBaseAddress + lengthOfC1Segment + lengthOfC3Segment; // std::cout << "New C1 address: " << newC1Address << std::endl; // std::cout << "New C3 address: " << newC3Address << std::endl; // std::cout << "Export address: " << exportAddress << std::endl; // Update all the code that references the old locations of C1 and C3 // Get the banked address for the new direct address of C1 int newC1BankNum = LoadedROM::directToBankNum(newC1Address); int newC1BankedAddress = LoadedROM::directToBankedAddress(newC1Address); // Get the banked address for the new direct address of C3 int newC3BankNum = LoadedROM::directToBankNum(newC3Address); int newC3BankedAddress = LoadedROM::directToBankedAddress(newC3Address); // Update bank number in code that calls C1 ByteConversion::toBytes(newC1BankNum, rom.directWrite(callReferenceToC1Bank), ByteSizes::uint8Size, EndiannessTypes::little, SignednessTypes::nosign); // C1's banked address is the same (0000), so we don't need to update it // ... but do anyway for consistency ByteConversion::toBytes(newC1BankedAddress, rom.directWrite(callReferenceToC1Address), ByteSizes::uint16Size, EndiannessTypes::little, SignednessTypes::nosign); // Update banked address in code that calls C3 ByteConversion::toBytes(newC3BankNum, rom.directWrite(callReferenceToC3Bank), ByteSizes::uint8Size, EndiannessTypes::little, SignednessTypes::nosign); // Update bank number in code that calls C3. ByteConversion::toBytes(newC3BankedAddress, rom.directWrite(callReferenceToC3Address), ByteSizes::uint16Size, EndiannessTypes::little, SignednessTypes::nosign); // C3 contains a hardcoded JP instruction into itself. Since we moved // C3, we have to update the JP to correspond to the new location. // Get new address of the JP instruction's address parameter Taddress addressOfNewJpParameter = newC3Address + offsetOfJpInC3; // Get new address of the JP instruction's jump point base Taddress addressOfNewJpBase = newC3Address + baseOffsetOfJpInC3; // Compute the new target address Taddress newJpTargetAddress = addressOfNewJpBase - absoluteLengthOfJpInC3; // std::cout << "New JP target: " << newJpTargetAddress << std::endl; // Convert to banked form Taddress newJpTargetBankedAddress = LoadedROM::directToBankedAddress(newJpTargetAddress); // Write the new target address to the JP parameter ByteConversion::toBytes(newJpTargetBankedAddress, rom.directWrite(addressOfNewJpParameter), ByteSizes::uint16Size, EndiannessTypes::little, SignednessTypes::nosign); // Get the banked address for the new direct address of the object table // int newTableBankNum // = LoadedROM::directToBankNum(exportAddress); int newTableBankedAddress = LoadedROM::directToBankedAddress(exportAddress); // Update C1 to refer to the new location of the object table ByteConversion::toBytes(newTableBankedAddress, rom.directWrite(newC1Address + offsetOfTableReferenceInC1), ByteSizes::uint16Size, EndiannessTypes::little, SignednessTypes::nosign); // Update C3 to refer to the new location of the object table ByteConversion::toBytes(newTableBankedAddress, rom.directWrite(newC3Address + offsetOfTableReferenceInC3), ByteSizes::uint16Size, EndiannessTypes::little, SignednessTypes::nosign); // Update table information // initialTableAddress_ = exportAddress; // initialTableContentSize_ = spaceIt->length() // - exportAddress // - tableHeaderSize_; // initialTableContentSize_ = exportAddress - spaceIt->address() // - tableHeaderSize_; // initialTableContentSize_ = LoadedROM::bankSize; // std::cout << initialTableContentSize_ << std::endl; // Mark that we've moved to a new bank movedToNewBank_ = true; return exportAddress; }
void TailsAdvBank0Hacks::addButton1MaxHeightFixHack( WritableROM& rom) { rom.directWrite(button1MaxHeightFixHackAddress, button1MaxHeightFixHackData, button1MaxHeightFixHackLength); }
void TailsAdvBank0Hacks::addFlightDisableHack( WritableROM& rom) { rom.directWrite(flightDisableHackMainAddress, flightDisableHackMainData, flightDisableHackMainLength); }
void TailsAdvBank0Hacks::addNoGameOverHack( WritableROM& rom) { rom.directWrite(noGameOverHackMainAddress, noGameOverHackMainData, noGameOverHackMainLength); }
void TailsAdvBank0Hacks::addUseAllInventoryHack( WritableROM& rom) { // Find free space FreeSpaceList::iterator spaceIt = rom.freeSpace().getFreeSpace(allInventoryHackCodeDataSize); // Throw if not enough space if (spaceIt == rom.freeSpace().freeSpaceList().end()) { throw NotEnoughSpaceException(TALES_SRCANDLINE, "TailsAdvBank0Hacks::addUseAllInventoryHack(" "WritableROM&)", allInventoryHackCodeDataSize); } Taddress writeAddress = spaceIt->address(); rom.freeSpace().claimSpace(spaceIt, allInventoryHackCodeDataSize); // std::cout << writeAddress << std::endl; // Write main code and data rom.directWrite(writeAddress, allInventoryHackMainData, allInventoryHackMainLength); // Fill in addresses of data tables ByteConversion::toBytes(LoadedROM::directToBankedAddress(writeAddress + allInventoryHackMainTable1Offset), rom.directWrite(writeAddress + allInventoryHackMainTable1ReferenceOffset), ByteSizes::uint16Size, EndiannessTypes::little, SignednessTypes::nosign); ByteConversion::toBytes(LoadedROM::directToBankedAddress(writeAddress + allInventoryHackMainTable2Offset), rom.directWrite(writeAddress + allInventoryHackMainTable2ReferenceOffset), ByteSizes::uint16Size, EndiannessTypes::little, SignednessTypes::nosign); // Add trigger 1 rom.directWrite(allInventoryHackTrigger1Address, allInventoryHackTrigger1Data, allInventoryHackTrigger1Length); // Fill in bank ByteConversion::toBytes(LoadedROM::directToBankNum(writeAddress + allInventoryHackMainCodeStartOffset), rom.directWrite( allInventoryHackTrigger1Address + allInventoryHackTrigger1BankReferenceOffset), ByteSizes::uint8Size, EndiannessTypes::little, SignednessTypes::nosign); // Fill in address ByteConversion::toBytes(LoadedROM::directToBankedAddress(writeAddress + allInventoryHackMainCodeStartOffset), rom.directWrite( allInventoryHackTrigger1Address + allInventoryHackTrigger1AddressReferenceOffset), ByteSizes::uint16Size, EndiannessTypes::little, SignednessTypes::nosign); // Add trigger 2 rom.directWrite(allInventoryHackTrigger2Address, allInventoryHackTrigger2Data, allInventoryHackTrigger2Length); // Fill in bank ByteConversion::toBytes(LoadedROM::directToBankNum(writeAddress + allInventoryHackMainCodeStartOffset), rom.directWrite( allInventoryHackTrigger2Address + allInventoryHackTrigger2BankReferenceOffset), ByteSizes::uint8Size, EndiannessTypes::little, SignednessTypes::nosign); // Fill in address ByteConversion::toBytes(LoadedROM::directToBankedAddress(writeAddress + allInventoryHackMainCodeStartOffset), rom.directWrite( allInventoryHackTrigger2Address + allInventoryHackTrigger2AddressReferenceOffset), ByteSizes::uint16Size, EndiannessTypes::little, SignednessTypes::nosign); // Add initializer 1 rom.directWrite(allInventoryHackInitializer1Address, allInventoryHackInitializer1Data, allInventoryHackInitializer1Length); // Add initializer 2 rom.directWrite(allInventoryHackInitializer2Address, allInventoryHackInitializer2Data, allInventoryHackInitializer2Length); // Add initializer 3 rom.directWrite(allInventoryHackInitializer3Address, allInventoryHackInitializer3Data, allInventoryHackInitializer3Length); // Add initializer 4 rom.directWrite(allInventoryHackInitializer4Address, allInventoryHackInitializer4Data, allInventoryHackInitializer4Length); }