00000000 AdvMgr              struc ; (sizeof=0x258, mappedto_380)
00000000 field_0             db 548 dup(?)                           ; string(C)
00000224 cachedLoopsSoundsMask dd ?                                  ; DEPRECATED
00000228 cachedLoopSounds    HeroClosestLoopSound 4 dup(?)
00000248 cachedLoopSoundWavs dd 4 dup(?)                             ; offset
00000258 AdvMgr              ends
00000258
00000000 ; ---------------------------------------------------------------------------
00000000
00000000 HeroClosestLoopSound struc ; (sizeof=0x8, mappedto_381)     ; XREF: AdvMgr/r
00000000 loopSoundId         dd ?
00000004 distance            dd ?
00000008 HeroClosestLoopSound ends
418B70 void __thiscall MapItem_Start_Loop_Sound(AdvMgr *advMgr, int x, int y, int z, int distance, int allowCaching)
{
  AdvMgr *self; // esi
  signed int determinedLoopSoundId; // edi
  AdvMgrConsts cachedLoopSoundIndex; // eax
  HeroClosestLoopSound *cachedLoopSound; // ecx
  int farthestDistance; // edx
  signed int newLoopSoundIndex; // ebx
  AdvMgrConsts i; // eax
  int prevLoopSoundId; // eax
  int *soundDistanceToCheck; // [esp+14h] [ebp+8h]
  self = advMgr;
  if ( x >= 0 && y >= 0 && z >= 0 && x < MapSizeX && y < MapSizeY )
  {
    determinedLoopSoundId = AdvMgr_MapItem_Determine_Sound(x, y, z);
    if ( determinedLoopSoundId != -1 )
    {
      cachedLoopSoundIndex = 0;
      cachedLoopSound = self->cachedLoopSounds;
      while ( cachedLoopSound->loopSoundId != determinedLoopSoundId )
      {
        ++cachedLoopSoundIndex;
        ++cachedLoopSound;
        if ( cachedLoopSoundIndex >= MAX_CACHED_LOOP_SOUNDS )// Such looped sound not found in cache
        {
          if ( allowCaching != 1 )
          {
            farthestDistance = distance;
            newLoopSoundIndex = -1;
            i = 0;
            soundDistanceToCheck = &self->cachedLoopSounds[0].distance;
            do
            {
              if ( *soundDistanceToCheck > farthestDistance )
              {
                farthestDistance = *soundDistanceToCheck;
                newLoopSoundIndex = i;
              }
              ++i;
              soundDistanceToCheck += 2;
            }
            while ( i < MAX_CACHED_LOOP_SOUNDS );
            if ( newLoopSoundIndex != -1 )
            {
              prevLoopSoundId = self->cachedLoopSounds[newLoopSoundIndex].loopSoundId;
              if ( prevLoopSoundId != -1 )
                StopBINKVideo_AIL(o_SoundMgr, *(self->cachedLoopSoundWavs[prevLoopSoundId] + 7));
              self->cachedLoopSounds[newLoopSoundIndex].loopSoundId = determinedLoopSoundId;
              self->cachedLoopSounds[newLoopSoundIndex].distance = distance;
              if ( determinedLoopSoundId > -1
                && determinedLoopSoundId < 70
                && !self->cachedLoopSoundWavs[determinedLoopSoundId] )
              {
                Dlg_KingdomOverviewPrepare(self, 4);
                self->cachedLoopSoundWavs[determinedLoopSoundId] = LoadWAV2((&off_0065F794)[determinedLoopSoundId]);
              }
              *(self->cachedLoopSoundWavs[determinedLoopSoundId] + 11) = dword_0063A64C[distance];
              *(self->cachedLoopSoundWavs[determinedLoopSoundId] + 12) = 0;
              *(self->cachedLoopSoundWavs[determinedLoopSoundId] + 10) = 3;
              NotifyPlayerWithBINKandSound(o_SoundMgr, self->cachedLoopSoundWavs[determinedLoopSoundId]);
              self->cachedLoopsSoundsMask ^= 1 << self->cachedLoopSounds[newLoopSoundIndex].loopSoundId;
            }
          }
          return;
        }
      }
      if ( self->cachedLoopSounds[cachedLoopSoundIndex].distance > distance )
      {
        self->cachedLoopSounds[cachedLoopSoundIndex].distance = distance;
        self->cachedLoopsSoundsMask |= 1 << self->cachedLoopSounds[cachedLoopSoundIndex].loopSoundId;
      }
    }
  }
}