Beco: Difference between revisions

220 bytes removed ,  2 years ago
→‎Getting data for a given coordinate: replace pseudocode with actual C++ source code (from the decomp project)
imported>Leoetlino
No edit summary
(→‎Getting data for a given coordinate: replace pseudocode with actual C++ source code (from the decomp project))
 
(5 intermediate revisions by one other user not shown)
Line 42: Line 42:
== Operations ==
== Operations ==


=== Getting the custom data for a given coordinate ===
=== Getting data for a given coordinate ===
{{expand section}}
The algorithm that returns the custom data that is associated with a coordinate is very simple. It consists of determining the correct row index in the table, then iterating over segments in that row and returning the segment data when the X coordinate is within its bounds.


At 0x7100E41C40 in Switch 1.5.0:
<syntaxhighlight lang="c++">
s32 Ecosystem::getMapArea(const EcoMapInfo& info, f32 posX, f32 posZ) const {
    posX = sead::Mathf::clamp(posX, -5000.0f, 4999.0f);
    posZ = sead::Mathf::clamp(posZ, -4000.0f, 4000.0f);


<syntaxhighlight lang="c++">
    const auto epsilon = [](float n) { return n >= 0.0f ? 0.5f : -0.5f; };
unsigned int __fastcall eco::getCurrentAreaNum(float posX, float posZ, Ecosystem *ecosystem, EcoMapInfo *info)
{
  float _x; // s2
  float _z; // s0
  int divisor; // w10
  int numEntries; // w12
  float v8; // s4
  signed int c_x; // w8
  float v10; // s0
  float v11; // s1
  int c_z; // w9
  int idx; // w9
  u32 *v14; // x9
  __int64 v15; // x10
  __int64 v16; // x11
  EcoMapEntry *tables; // x12
  EcoMapEntry *_entryEnd; // x11
  EcoMapEntry *_entry; // x10
  signed int totalLength; // w9
  unsigned int result; // w0


  _x = -5000.0;
    s32 x = s32(posX + 5000.0f + epsilon(posX + 5000.0f));
  if ( posX >= -5000.0 )
     s32 z = s32(posZ + 4000.0f + epsilon(posZ + 4000.0f)) / info.mHeader->divisor;
  {
     s32 row = sead::Mathi::clamp(z, 0, info.mHeader->num_rows - 2);
     _x = posX;
    if ( posX > 4999.0 )
      _x = 4999.0;
  }
  _z = -4000.0;
  if ( posZ >= -4000.0 )
  {
     _z = posZ;
    if ( posZ > 4000.0 )
      _z = 4000.0;
  }


  divisor = info->map->divisor;
     if (info.mHeader->divisor == 10)
  numEntries = info->map->numTables - 2;
        x /= 10;
  if ( (float)(_x + 5000.0) < 0.0 )
    v8 = -0.5;
  else
     v8 = 0.5;
  c_x = (signed int)(float)((float)(_x + 5000.0) + v8);
  v10 = _z + 4000.0;
  if ( v10 < 0.0 )
    v11 = -0.5;
  else
    v11 = 0.5;
  c_z = (signed int)(float)(v10 + v11) / divisor;
  if ( c_z <= numEntries )
    numEntries = (signed int)(float)(v10 + v11) / divisor;
  if ( c_z >= 0 )
    idx = numEntries;
  else
    idx = 0;


  v14 = &info->tableOffsets[idx];
    if (info.mRowOffsets[row] >= info.mRowOffsets[row + 1])
  if ( divisor == 0xA )
        return -1;
    c_x = (0x66666667LL * c_x >> 0x22) + ((unsigned __int64)(0x66666667LL * c_x) >> 0x3F);
  v15 = (signed int)*v14;
  v16 = (signed int)v14[1];
  if ( (signed int)v15 >= (signed int)v16 )
    return 0xFFFFFFFF;


  tables = info->tables;
    auto* segmentEnd = reinterpret_cast<const Segment*>(info.mRows + 2 * info.mRowOffsets[row + 1]);
  _entryEnd = (EcoMapEntry *)((char *)tables + 2 * v16);
    auto* segment = reinterpret_cast<const Segment*>(info.mRows + 2 * info.mRowOffsets[row]);
  _entry = (EcoMapEntry *)((char *)tables + 2 * v15);
    s32 totalLength = 0;
  totalLength = 0;
    while (true) {
  result = 0xFFFFFFFF;
        totalLength += segment->length;
  while ( 1 )
        if (x < totalLength)
  {
            break;
    totalLength += _entry->length;
        ++segment;
    if ( c_x < totalLength )
        if (segment >= segmentEnd)
      break;
            return -1;
    ++_entry;
    }
    if ( _entry >= _entryEnd )
    return segment->value;
      return result;
  }
  return _entry->value;
}
}
</syntaxhighlight>
</syntaxhighlight>
Source: https://github.com/zeldaret/botw/blob/022f029db1ef03d900fb54bad0807939c9695720/src/KingSystem/Ecosystem/ecoSystem.cpp#L100
== Usage in ''Breath of the Wild'' ==
beco files are used in ''Breath of the Wild'' to map coordinates to arbitrary u16 data. Three beco files are used for different purposes: [[FieldMapArea.beco]], [[MapTower.beco]] and [[LoadBalancer.beco]].


[[Category:File formats]]
[[Category:File formats]]
[[Category:File extensions]]
[[Category:File extensions]]