Beco: Difference between revisions

1,802 bytes added ,  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))
 
(9 intermediate revisions by one other user not shown)
Line 1: Line 1:
{{lowercase}}
'''beco''' is a file format that is used for storing per-coordinate data.
'''beco''' is a file format that is used for storing per-coordinate data.


Line 11: Line 12:
| 0x0 || u32 || Magic (0x00112233)
| 0x0 || u32 || Magic (0x00112233)
|-
|-
| 0x4 || u32 || Number of tables
| 0x4 || u32 || Number of rows
|-
|-
| 0x8 || u32 || Divisor
| 0x8 || u32 || Divisor
Line 18: Line 19:
|}
|}


=== Table offsets ===
=== Offsets ===
{| class="wikitable"
{| class="wikitable"
|-
|-
! Offset !! Type !! Description
! Offset !! Type !! Description
|-
|-
| 0x0 || u32[num_tables] || Offsets to table data, divided by 2 and relative to table data start offset
| 0x0 || u32[num_rows] || Offsets to row data, divided by 2 and relative to the start of the row section
|}
|}


=== Table ===
=== Rows ===
Table data starts here.
 
==== Segment ====
==== Segment ====
{| class="wikitable"
{| class="wikitable"
Line 39: Line 38:
|}
|}


This structure is repeated until the start of the next table.
This structure is repeated until the entire row has been covered by segments. The sum of all segment lengths is equal to the length of the map on the X axis.  


== Operations ==
== Operations ==


=== Getting the custom data for a given coordinate ===
=== Getting data for a given coordinate ===
{{Empty 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.
 
<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);
 
    const auto epsilon = [](float n) { return n >= 0.0f ? 0.5f : -0.5f; };
 
    s32 x = s32(posX + 5000.0f + epsilon(posX + 5000.0f));
    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);
 
    if (info.mHeader->divisor == 10)
        x /= 10;
 
    if (info.mRowOffsets[row] >= info.mRowOffsets[row + 1])
        return -1;
 
    auto* segmentEnd = reinterpret_cast<const Segment*>(info.mRows + 2 * info.mRowOffsets[row + 1]);
    auto* segment = reinterpret_cast<const Segment*>(info.mRows + 2 * info.mRowOffsets[row]);
    s32 totalLength = 0;
    while (true) {
        totalLength += segment->length;
        if (x < totalLength)
            break;
        ++segment;
        if (segment >= segmentEnd)
            return -1;
    }
    return segment->value;
}
</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]]