EditablePowerUpData::EditablePowerUpData(LoadedROM& rom,
                                         Taddress powerUpTableAddress__)
  : powerUpTableAddress_(powerUpTableAddress__) {
  int byteCount = 0;
  
  for (int i = 0; i < numPowerUps_; i++) {
    // Get binary-coded decimal representation of max health
    int maxHealthBCD = ByteConversion::fromBytes(
                            rom.directRead(powerUpTableAddress_ + byteCount),
                            ByteSizes::uint8Size,
                            EndiannessTypes::little,
                            SignednessTypes::nosign);
    byteCount += ByteSizes::uint8Size;
    
    // Convert to standard integer format
    int maxHealth = MiscMath::fromBCD(maxHealthBCD);
    
    // Store
    maxHealthPerPowerup_[i] = maxHealth;
    
    // Get flight time
    int flightTime = ByteConversion::fromBytes(
                            rom.directRead(powerUpTableAddress_ + byteCount),
                            ByteSizes::uint16Size,
                            EndiannessTypes::little,
                            SignednessTypes::nosign);
    byteCount += ByteSizes::uint16Size;
    
    // Store
    flightTimePerPowerup_[i] = flightTime;
  }
}
示例#2
0
WritableROM::WritableROM(
              const LoadedROM& rom__,
              const FreeSpaceListing& freeSpace__)
  : rom_(new Tbyte[rom__.loadedFileSize()]),
    romSize_(rom__.loadedFileSize()),
    freeSpace_(freeSpace__) {
  // Copy contents of ROM
  std::memcpy((char*)rom_,
              (char*)(rom__.directRead(0)),
              rom__.loadedFileSize());
}
EditableLevelObjectEntryGroups::EditableLevelObjectEntryGroups(
                         LoadedROM& rom,
                         Taddress tableHeaderAddress,
                         Taddress tableContentAddress,
                         Taddress tableEndAddress,
                         int numEntries)
  : TwoKeyIndexedEditableMappedData<LevelObjectEntryGroup>(rom,
                                 tableHeaderAddress,
                                 tableContentAddress,
                                 tableEndAddress,
                                 numEntries,
                                 SubMaps::subMapLevelObjectTableCounts,
                                 primaryMapLimit),
    movedToNewBank_(false),
    tableHeaderSize_(tableContentAddress - tableHeaderAddress),
    initialTableAddress_(tableHeaderAddress),
    initialTableContentSize_(tableEndAddress - tableContentAddress) {
    
    // For seemingly no reason except to f**k us over, some of the
    // table entries are non-contiguous, so we can't use this
/*  readAllDataAndConstruct(rom,
                   tableHeaderAddress,
                   tableContentAddress,
                   tableEndAddress,
                   numEntries); */
                   
//  std::cout << "****** THIS ONE ********" << std::endl;
                   
  readAndConstruct(rom,
                   tableHeaderAddress,
                   tableEndAddress);
                   
//  std::cout << mapnumToAddress_.numPrimaryKeys() << std::endl;
  
  // Copy C1 and C3 code segments for exporting
  
  std::memcpy(codeSegmentC1,
              rom.directRead(addressOfC1Segment),
              lengthOfC1Segment);
              
  std::memcpy(codeSegmentC3,
              rom.directRead(addressOfC3Segment),
              lengthOfC3Segment);
  
}
RawObjectGraphicsHeader::RawObjectGraphicsHeader(
                       LoadedROM& rom,
                       Taddress address) {
  Taddress readAddress = address;
  Tbyte endOfHeaderCheck = *(rom.directRead(readAddress));
  while (endOfHeaderCheck != endOfHeaderToken) {
    // Read subheader
    RawObjectGraphicSubheader subheader(rom,
                                        readAddress);
    
    // Add to storage
    rawObjectGraphicSubheaders_.push_back(subheader);
    
    // Move to next subheader address
    readAddress += RawObjectGraphicSubheader::dataSize;
    
    // Check for end of header
    endOfHeaderCheck = *(rom.directRead(readAddress));
  }
}
EditableSlopeSpeedValues::EditableSlopeSpeedValues(LoadedROM& rom,
                         Taddress baseAddress__,
                         int numEntries)
  : baseAddress_(baseAddress__) {
  for (int i = 0; i < numEntries; i++) {
    int value = ByteConversion::fromBytes(
                            rom.directRead(baseAddress__
                              + (i * ByteSizes::int16Size)),
                            ByteSizes::int16Size,
                            EndiannessTypes::little,
                            SignednessTypes::sign);
    speedValues_.push_back(value);
  }
}
void EditableLevelObjectEntryGroups::readAndConstructReadStep(
                                      LoadedROM& rom,
                                      Taddress tableEndAddress) {
  // Iterate over primary storage addresses and read corresponding data
  for (AddressIndexMap::iterator it = addressToIndex_.begin();
       it != addressToIndex_.end();
       ++it) {
//      std::cout << "start: " << it->first << std::endl;
    
    Taddress startAddress = it->first;
    
    // Read elements in array
    LevelObjectEntryGroup dst;
    readElements(dst,
                 rom.directRead(startAddress),
                 1);
    
    // Add read elements to primary storage
    primaryStorage_[it->second] = LevelObjectEntryGroup(dst);
  }
}
示例#7
0
int MetatileStructureSet::readFromData(LoadedROM& rom,
                                               Taddress address__) {
  address_ = address__;
  
  // Count of read bytes
  int byteCount = 0;
                                               
  // Get bank number of the table
  int tableBankNum = LoadedROM::directToBankNum(address__);
  
  // Compute table size.
  // The first address in the index always points to the first
  // structure definition
  Taddress contentStartBankedAddress = ByteConversion::fromBytes(
        rom.directRead(address__),
        ByteSizes::uint16Size,
        EndiannessTypes::little,
        SignednessTypes::nosign);
  
  // Convert to direct address
  Taddress contentStartAddress = 0;
  if (contentStartBankedAddress == invalidStructureToken) {
    contentStartAddress = invalidRepairAddress;
  }
  else {
    contentStartAddress = LoadedROM::getDirectAddress(
                                              tableBankNum,
                                              contentStartBankedAddress);
  }
  
  // Get size of index, given by ((tableStart - indexStart) / entrySize)
  int indexEntries = (contentStartAddress - address__) / ByteSizes::uint16Size;
  
  // Read the index.
  // Remember the highest index we encounter
  int highestIndex = 0;
  for (int i = 0; i < indexEntries; i++) {
    // Get banked address
    Taddress entryBankedAddress = ByteConversion::fromBytes(
          rom.directRead(address__ + (i * ByteSizes::uint16Size)),
          ByteSizes::uint16Size,
          EndiannessTypes::little,
          SignednessTypes::nosign);
    byteCount += ByteSizes::uint16Size;
    
    // Convert to direct address
    int entryAddress = 0;
    // If address is invalid, repair
    if (entryBankedAddress == invalidStructureToken) {
//      std::cout << contentStartAddress << std::endl;
      entryAddress = invalidRepairAddress
                             + (i * MetatileStructure::dataSize);
    }
    else {
      entryAddress = LoadedROM::getDirectAddress(
                                        tableBankNum,
                                        entryBankedAddress);
    }
    
    // Compute the actual index this address corresponds to
    int structureIndex = (entryAddress - contentStartAddress)
          / MetatileStructure::dataSize;
    
    // Add mapping to index map
    index_.insert(MetatileIndexToStructurePair(i, structureIndex));
    
    if (structureIndex > highestIndex) {
      highestIndex = structureIndex;
    }
  }
  
  // Increment highest index (we're using it as a limit for the read loop)
  ++highestIndex;
  
  // Read the structure definitions.
  // The highest index indicates the actual number of structure definitions
  // in the table
  for (int i = 0; i < highestIndex; i++) {
    // Read each metatile
    MetatileStructure metatile;
    metatile.readFromData(rom.directRead(contentStartAddress
                            + (i * MetatileStructure::dataSize)));
    
    // If reading invalid table, repair tiles
    if (contentStartAddress == invalidRepairAddress) {
//      std::cout << highestIndex << std::endl;
      metatile.upperLeft() = TileReference(invalidRepairTile);
      metatile.upperRight() = TileReference(invalidRepairTile);
      metatile.lowerLeft() = TileReference(invalidRepairTile);
      metatile.lowerRight() = TileReference(invalidRepairTile);
    }
    
    // Add to content
    primaryStorage_.push_back(metatile);
    
    byteCount += MetatileStructure::dataSize;
  }
  
  // HACK: (sort of) Add dummy entries to fill rest of set.
  // This fixes issues that I think are caused by out-of-range
  // values in the index.
//  while (primaryStorage_.size() < 256) {
//    primaryStorage_.push_back(MetatileStructure());
//  }
  
  return byteCount;
}
EditableLevelPaletteHeaders::EditableLevelPaletteHeaders(
                            LoadedROM& rom,
                            Taddress tableHeaderAddress__,
                            Taddress tableContentAddress__,
                            int numContentEntries,
                            const int subKeyTable[],
                            int numPrimaryKeys)
  : mapnumToIndex_(subKeyTable,
                   numPrimaryKeys),
    tableHeaderAddress_(tableHeaderAddress__),
    tableContentAddress_(tableContentAddress__) {
  // Read the key index table
  
  int tableHeaderReadAddress = tableHeaderAddress_;
  for (int i = 0; i < mapnumToIndex_.numPrimaryKeys(); i++) {
    // Only set index if there is at least one submap
    if (mapnumToIndex_.subKeyTable()[i] > 0) {
      // Get banked address of data
      Taddress address
        = ByteConversion::fromBytes(
                            rom.directRead(tableHeaderReadAddress),
                            ByteSizes::uint16Size,
                            EndiannessTypes::little,
                            SignednessTypes::nosign);
      
      int index = LoadedROM::toIndex(
                             tableContentAddress_,
                             address,
                             LevelPaletteHeader::dataSize);
//      std::cout << "address: " << address << std::endl;
//      std::cout << "index: " << index << std::endl;
//      std::cout << "aewtnio: " << i << std::endl;
      
      // Convert address to index and store
      mapnumToIndex_.refDataByKeys(i, TwoKeyedAddress::subKeyBase)
        = index;
    }
    
    tableHeaderReadAddress += ByteSizes::uint16Size;
    
//    for (int j = 0; j < mapnumToIndex_.subKeyTable()[i]; j++) {
//    }
  }
  
  // This particular header table has a different format from most others:
  // there is a single table of primary map numbers to addresses, and
  // the game simply adds the appropriate amount for the submap to that
  // address
  // We simulate this by setting higher indices correspondingly
  for (int i = 0; i < mapnumToIndex_.numPrimaryKeys(); i++) {
    int nextIndex = 0;
    
    // Only get index if there is at least one submap
    if (mapnumToIndex_.subKeyTable()[i] > 0) {
      // Get the index for the first submap of the current primary map
      nextIndex = mapnumToIndex_.refDataByKeys(i,
                                               TwoKeyedAddress::subKeyBase);
      // Advance to next position;
      ++nextIndex;
      
    }
    for (int j = 1; j < mapnumToIndex_.subKeyTable()[i]; j++) {
      // Set each submap to the previous map plus one
      mapnumToIndex_.refDataByKeys(i, j + TwoKeyedAddress::subKeyBase)
        = nextIndex;
      ++nextIndex;
    }
  }
  
  // Read actual header entries
  int tableContentReadAddress = tableContentAddress_;
  for (int i = 0; i < numContentEntries; i++) {
    LevelPaletteHeader header;
    
    tableContentReadAddress
      += header.readFromData(rom.directRead(tableContentReadAddress));
      
    primaryStorage_.push_back(header);
  }
}