changeset 389:e32950ebabb9

Merge
author Nomad
date Sat, 23 Feb 2013 04:02:05 +0200
parents d95a91011d57 (diff) 84f53d7fc96d (current diff)
children 35a62d1948d4
files mm7_5.cpp
diffstat 8 files changed, 341 insertions(+), 305 deletions(-) [+]
line wrap: on
line diff
--- a/AIL.cpp	Sat Feb 23 01:56:42 2013 +0400
+++ b/AIL.cpp	Sat Feb 23 04:02:05 2013 +0200
@@ -35,7 +35,7 @@
 void (__stdcall *mss32_AIL_set_sample_loop_count)(HSAMPLE, int) = 0;
 void (__stdcall *mss32_AIL_set_sample_playback_rate)(HSAMPLE, int) = 0;
 void (__stdcall *mss32_AIL_sample_ms_position)(HSAMPLE, int *, int *) = 0;
-void (__stdcall *mss32_AIL_start_sample)(HSAMPLE) = 0;
+int (__stdcall *mss32_AIL_start_sample)(HSAMPLE) = 0;
 AILFILETYPE (__stdcall *mss32_AIL_file_type)(void *, int) = 0;
 int (__stdcall *mss32_AIL_WAV_info)(void *, AILSOUNDINFO *) = 0;
 int (__stdcall *mss32_AIL_decompress_ADPCM)(AILSOUNDINFO *, void *, void *) = 0;
@@ -77,7 +77,7 @@
  mss32_AIL_set_sample_loop_count = (void (__stdcall *)(HSAMPLE, int))GetProcAddress(pDll, "_AIL_set_sample_loop_count@8");
  mss32_AIL_set_sample_playback_rate = (void (__stdcall *)(HSAMPLE, int))GetProcAddress(pDll, "_AIL_set_sample_playback_rate@8");
  mss32_AIL_sample_ms_position = (void (__stdcall *)(HSAMPLE, int *, int *))GetProcAddress(pDll, "_AIL_sample_ms_position@12");
- mss32_AIL_start_sample = (void (__stdcall *)(HSAMPLE))GetProcAddress(pDll, "_AIL_start_sample@4");
+ mss32_AIL_start_sample = (int (__stdcall *)(HSAMPLE))GetProcAddress(pDll, "_AIL_start_sample@4");
  mss32_AIL_file_type = (AILFILETYPE (__stdcall *)(void *, int))GetProcAddress(pDll, "_AIL_file_type@8");
  mss32_AIL_WAV_info = (int (__stdcall *)(void *, AILSOUNDINFO *))GetProcAddress(pDll, "_AIL_WAV_info@8");
  mss32_AIL_decompress_ADPCM = (int (__stdcall *)(AILSOUNDINFO *, void *, void *))GetProcAddress(pDll, "_AIL_decompress_ADPCM@12");
@@ -171,10 +171,7 @@
 }
 
 void __stdcall AIL_3D_provider_attribute(HPROVIDER lib, char *name, void *val)
-{
- //__asm int 3
- //return 0;
- 
+{ 
  (mss32_AIL_3D_provider_attribute)(lib,name,val);
 }
 
@@ -210,9 +207,6 @@
 
 void __stdcall AIL_waveOutClose(HDIGDRIVER drvr)
 {
- //__asm int 3
- //return 0;
-
  (mss32_AIL_waveOutClose)(drvr);
 }
 
@@ -248,9 +242,6 @@
 
 void __stdcall AIL_release_sample_handle(HSAMPLE s)
 {
- //__asm int 3
- //return 0;
-
  (mss32_AIL_release_sample_handle)(s);
 }
 
@@ -262,20 +253,20 @@
 
 int __stdcall AIL_close_3D_provider(HPROVIDER)
 {
- //__asm int 3
+ __asm int 3
  return 0;
 }
 
 int __stdcall AIL_redbook_close(HREDBOOK a1)
 {
- //__asm int 3
+ __asm int 3
  return 0;
 }
 
 // sub_4D8344: using guessed type int __stdcall AIL_shutdown();
 int __stdcall AIL_shutdown()
 {
- //__asm int 3
+ __asm int 3
  return 0;
 }
 
@@ -306,9 +297,9 @@
  return (mss32_AIL_set_sample_file)(s, file_image, block);
 }
 
-void __stdcall AIL_start_sample(HSAMPLE s)
+int __stdcall AIL_start_sample(HSAMPLE s)
 {
- (mss32_AIL_start_sample)(s);
+ return (mss32_AIL_start_sample)(s);
 }
 
 void __stdcall AIL_set_sample_playback_rate(HSAMPLE s, int rate)
--- a/AIL.h	Sat Feb 23 01:56:42 2013 +0400
+++ b/AIL.h	Sat Feb 23 04:02:05 2013 +0200
@@ -272,7 +272,7 @@
 void __stdcall AIL_end_sequence(HSEQUENCE a1);
 void __stdcall AIL_pause_stream(HSTREAM a1, int onoff);
 int __stdcall AIL_set_sample_file(HSAMPLE, const void *file_image, int block);
-void __stdcall AIL_start_sample(HSAMPLE);
+int __stdcall AIL_start_sample(HSAMPLE);
 void __stdcall AIL_set_sample_playback_rate(HSAMPLE, int rate);
 void __stdcall AIL_sample_ms_position(HSAMPLE, int *pTotalMS, int *pCurrentMS);
 int __stdcall AIL_3D_sample_status(void *a1);
--- a/Actor.cpp	Sat Feb 23 01:56:42 2013 +0400
+++ b/Actor.cpp	Sat Feb 23 04:02:05 2013 +0200
@@ -3286,7 +3286,7 @@
       v8 = 0;
     }
     v7 = 8 * uActorID;
-    LOBYTE(v7) = 8 * uActorID | 3;
+    LOBYTE(v7) = 8 * uActorID | OBJECT_Actor;
     pAudioPlayer->PlaySound((SoundID)(signed __int16)v3, v7, 0, v8, v9, v10, v11, v12);
   }
 }
--- a/AudioPlayer.cpp	Sat Feb 23 01:56:42 2013 +0400
+++ b/AudioPlayer.cpp	Sat Feb 23 04:02:05 2013 +0200
@@ -628,8 +628,8 @@
 void AudioPlayer::PlaySound(SoundID eSoundID, signed int a3, unsigned int uNumRepeats, signed int PartyX, signed int PartyY, int a7, unsigned int uVolume, int sPlaybackRate)
 {
   //AudioPlayer *pAudioPlayer1; // esi@1
-  signed int pNum; // edx@5
-  int *pSoundID; // ecx@6
+  //signed int pNum; // edx@5
+  //int *pSoundID; // ecx@6
   int v12; // edi@13
   signed int v13; // ecx@17
   signed int v14; // eax@20
@@ -657,7 +657,7 @@
   signed int v36; // ebx@74
   //AudioPlayer *pAudioPlayer2; // edi@79
   AudioPlayer_3DSample *pAudioPlayer_3DSample3; // esi@79
-  unsigned int v39; // ebx@80
+  //unsigned int v39; // ebx@80
   int v40; // eax@81
   char *v41; // edi@82
   int v42; // esi@82
@@ -676,44 +676,44 @@
   //AudioPlayer *pAudioPlayer3; // edx@106
   SoundDesc *pSoundDesc; // edx@107
   LayingItem *pLayingItem3; // eax@114
-  int v58; // edx@115
-  int v59; // ecx@115
-  Actor *pActor2; // eax@118
-  MixerChannel *pMixerChannel; // esi@126
+  //int v58; // edx@115
+  //int v59; // ecx@115
+  //Actor *pActor2; // eax@118
+  //MixerChannel *pMixerChannel; // esi@126
   signed int v62; // esi@133
   //AudioPlayer *pAudioPlayer4; // ebx@133
-  MixerChannel *pMixerChannel2; // edi@134
-  int v65; // ebx@141
+  //MixerChannel *pMixerChannel2; // edi@134
+  //int v65; // ebx@141
   //AudioPlayer *pAudioPlayer5; // ecx@142
-  MixerChannel *pMixerChannel3; // edi@142
+  //MixerChannel *pMixerChannel3; // edi@142
   int v68; // eax@143
-  MixerChannel *pMixerChannel4; // edi@149
-  int v70; // ecx@152
-  SoundDesc *pSoundDesc2; // eax@153
-  int v72; // edi@156
-  MixerChannel *pMixerChannel5; // esi@157
-  unsigned int pVolume; // eax@157
-  int pPartyX; // ebx@159
-  int v76; // ebx@160
-  LayingItem *pLayingItem4; // edi@164
-  unsigned int pPosY; // edx@166
-  unsigned int pPosX; // ecx@166
-  int v80; // eax@167
-  Actor *pActor3; // edi@168
-  BLVDoor *pBLVDoor2; // edi@173
-  int v83; // eax@183
-  int v84; // eax@183
-  _SAMPLE *v85; // ST18_4@186
+  //MixerChannel *pMixerChannel4; // edi@149
+  //int v70; // ecx@152
+  //SoundDesc *pSoundDesc2; // eax@153
+  //int v72; // edi@156
+  //MixerChannel *pMixerChannel5; // esi@157
+  //unsigned int pVolume; // eax@157
+  //int pPartyX; // ebx@159
+  //int v76; // ebx@160
+  //LayingItem *pLayingItem4; // edi@164
+  //unsigned int pPosY; // edx@166
+  //unsigned int pPosX; // ecx@166
+  //int v80; // eax@167
+  //Actor *pActor3; // edi@168
+  //BLVDoor *pBLVDoor2; // edi@173
+  //int v83; // eax@183
+  //int v84; // eax@183
+  //_SAMPLE *v85; // ST18_4@186
   unsigned int v86; // [sp+14h] [bp-60h]@84
-  int v87; // [sp+14h] [bp-60h]@115
+  //int v87; // [sp+14h] [bp-60h]@115
   RenderVertexSoft pRenderVertexSoft; // [sp+24h] [bp-50h]@1
-  unsigned int v89; // [sp+54h] [bp-20h]@12
+  //unsigned int v89; // [sp+54h] [bp-20h]@12
   int v90; // [sp+58h] [bp-1Ch]@68
   float v91; // [sp+5Ch] [bp-18h]@68
   //unsigned int v92; // [sp+60h] [bp-14h]@10
   float v93; // [sp+64h] [bp-10h]@1
   signed int varC; // [sp+68h] [bp-Ch]@68
-  AudioPlayer *pAudioPlayer; // [sp+6Ch] [bp-8h]@1
+  //AudioPlayer *pAudioPlayer; // [sp+6Ch] [bp-8h]@1
   int v96; // [sp+70h] [bp-4h]@19
   signed int uNumRepeatsb; // [sp+84h] [bp+10h]@93
   float uNumRepeatsa; // [sp+84h] [bp+10h]@104
@@ -723,213 +723,208 @@
   int v102; // [sp+90h] [bp+1Ch]@60
   int v103; // [sp+90h] [bp+1Ch]@68
 
-  pAudioPlayer = this;
-  v35 = this->bPlayerReady == 0;
-  //pAudioPlayer = this;
-  pRenderVertexSoft.flt_2C = 0.0;
-  LODWORD(v93) = 10000;
-  if ( v35 || !uSoundVolumeMultiplier || !this->hDigDriver || !eSoundID )
+  if (!bPlayerReady)
+    return;
+  if (!uSoundVolumeMultiplier)
+    return;
+  if (!hDigDriver)
+    return;
+  if (eSoundID == SOUND_Invalid)
     return;
- pNum = 0;
-  if ( (signed int)pSoundList->uNumSounds <= 0 )
-  {
-LABEL_9:
-    pNum = 0;
-  }
-  else
+
+  //pAudioPlayer = this;
+  //v35 = this->bPlayerReady == 0;
+  //pAudioPlayer = this;
+  //LODWORD(v93) = 10000;
+  int sample_volume = 10000;
+
+
+  int sound_id = 0;
+  for (uint i = 0; i < pSoundList->uNumSounds; ++i)
+    if (pSoundList->pSounds[i].uSoundID == eSoundID)
+    {
+      sound_id = i;
+      break;
+    }
+
+  if (!sound_id)
   {
-    pSoundID = (int *)&pSoundList->pSounds->uSoundID;
-    while ( *pSoundID != eSoundID )
-    {
-      ++pNum;
-      pSoundID += 30;
-      if ( pNum >= (signed int)pSoundList->uNumSounds )
-        goto LABEL_9;
-    }
+    Log::Warning(L"SoundID = %u not found", eSoundID);
+    return;
   }
-  /* v92 = pNum;//38 
- pNum = 0;
-  for ( pSoundID = (int *)&pSoundList->pSounds->uSoundID; *pSoundID != eSoundID; pSoundID += 30)
-  {
-    ++pNum;
-  }*/
-  if ( !pNum )
-    return;
-  if ( !pAudioPlayer->b3DSoundInitialized || (v89 = 120 * pNum, !(pSoundList->pSounds[pNum].uFlags & 2)) )
+
+  int start_channel = 0,
+      end_channel = 0;
+
+  assert(sound_id < pSoundList->uNumSounds);
+  auto sound_desc = pSoundList->pSounds + sound_id;
+  if (!b3DSoundInitialized || sound_desc->Is3D())
   {
-    //pSoundDesc = (SoundDesc *)7;
-    if ( a3 < 0 )
+    if (!a3)  // generic sound like from UI
+    {
+      start_channel = 10;
+      end_channel = 12;
+      goto LABEL_133;
+    }
+    else if (a3 == -1)  // exclusive sounds - can override
     {
-      if ( a3 == -1 )
+      start_channel = 13;
+      end_channel = 13;
+      goto LABEL_133;
+    }
+    else
+    {
+      if (a3 < 0)    // exclusive sounds - no override
       {
-        varC = 13;
-        v96 = 13;
-        goto LABEL_133;
+        start_channel = 14;
+        end_channel = 14;
+        goto LABEL_123;
       }
-      varC = 14;
-      v96 = 14;
-LABEL_123:
-      if ( a3 )
+      else
       {
-        if ( a3 != -1 )
+        int object_type = a3 & 7,
+            object_id = a3 >> 7;
+        switch (object_type)
         {
-          LODWORD(v91) = 0;
-          if ( pAudioPlayer->uMixerChannels > 0 )
+          case OBJECT_BLVDoor:
+          case OBJECT_Player:
+          {
+            start_channel = 10;
+            end_channel = 12;
+            goto LABEL_133;
+          }
+          break;
+
+          case OBJECT_Actor:
+          {
+            start_channel = 0;
+            end_channel = 3;
+
+            assert(object_id < uNumActors);
+            auto actor = &pActors[object_id];
+
+            sample_volume = GetSoundStrengthByDistanceFromParty(actor->vPosition.x, actor->vPosition.y, actor->vPosition.z);
+            if (!sample_volume)
+              return;
+            goto LABEL_123;
+          }
+
+          case OBJECT_Decoration:
           {
-            pMixerChannel = pAudioPlayer->pMixerChannels;
-            do
-            {
-              if ( AIL_sample_status(pMixerChannel->hSample) == AIL::Sample::Playing && pMixerChannel->source_pid == a3
-                && AIL_sample_status(pMixerChannel->hSample) == AIL::Sample::Playing)
-              {
-                if ( pMixerChannel->uSourceTrackIdx == pNum )
-                  return;
-                AIL_end_sample(pMixerChannel->hSample);
-                _4ABE55(pMixerChannel);
-              }
-              ++LODWORD(v91);
-              ++pMixerChannel;
-            }
-            while ( SLODWORD(v91) < pAudioPlayer->uMixerChannels );
+            start_channel = 4;
+            end_channel = 4;
+
+            assert(object_id < uNumLevelDecorations);
+            auto decor = &pLevelDecorations[object_id];
+
+            sample_volume = GetSoundStrengthByDistanceFromParty(decor->vPosition.x, decor->vPosition.y, decor->vPosition.z);
+            if (!sample_volume)
+              return;
+            goto LABEL_123;
           }
+          break;
+
+          case OBJECT_Item:
+          {
+            start_channel = 5;
+            end_channel = 7;
+
+            assert(object_id < uNumLayingItems);
+            auto object = &pLayingItems[object_id];
+
+            sample_volume = GetSoundStrengthByDistanceFromParty(object->vPosition.x, object->vPosition.y, object->vPosition.z);
+            if (!sample_volume)
+              return;
+            goto LABEL_123;
+          }
+          break;
+
+          case OBJECT_BModel:
+          {
+            start_channel = 8;
+            end_channel = 9;
+            goto LABEL_123;
+          }
+          break;
+
+          default:
+            assert(false);
         }
       }
+    }
+
+
+
+
+
+
+LABEL_123:
+    for (uint i = 0; i < uMixerChannels; ++i)
+    {
+      auto channel = pMixerChannels + i;
+      if (channel->source_pid == a3 &&
+          AIL_sample_status(channel->hSample) == AIL::Sample::Playing)
+      {
+        if (channel->uSourceTrackIdx == sound_id)
+          return;                          // already playing the same sound from the same source - return
+
+        AIL_end_sample(channel->hSample);  // requested new sound from the same source - end & switch
+        _4ABE55(channel);
+      }
+    }
+
 LABEL_133:
-      v62 = varC;
+      v62 = start_channel;
       //pAudioPlayer4 = pAudioPlayer;
-      if ( varC <= v96 )
+      for (v62 = start_channel; v62 <= end_channel; ++v62)
       {
-        pMixerChannel2 = &pAudioPlayer->pMixerChannels[varC];
+        auto channel = pMixerChannels + v62;
+        if (AIL_sample_status(channel->hSample) == AIL::Sample::Done)
+        {
+          AIL_end_sample(channel->hSample);
+          if (channel->uSourceTrackIdx)
+            _4ABE55(channel);
+          break;
+        }
+      }
+      /*if ( start_channel <= end_channel)
+      {
+        pMixerChannel2 = &pAudioPlayer->pMixerChannels[start_channel];
         while ( AIL_sample_status(pMixerChannel2->hSample) != AIL::Sample::Done)
         {
           ++v62;
           ++pMixerChannel2;
-          if ( v62 > v96 )
+          if ( v62 > end_channel )
             goto LABEL_140;
         }
         AIL_end_sample(pMixerChannel2->hSample);
         if ( pMixerChannel2->uSourceTrackIdx )
           _4ABE55(pMixerChannel2);
       }
-LABEL_140:
-      if ( v62 != v96 + 1 )//10!=13
+LABEL_140:*/
+
+      if (v62 > end_channel)  // no free channel - occupy the quitest one
       {
-LABEL_150:
-        if ( LODWORD(v93) == 10000 )
-          LODWORD(v93) = pAudioPlayer->uMasterVolume;
-        v70 = 0;
-        if ( !a7 )
+        v62 = -1;
+
+        int min_volume = sample_volume;
+        for (uint i = start_channel; i <= end_channel; ++i)
         {
-          //pSoundDesc = pSoundList->pSounds;
-          pSoundDesc2 = &pSoundList->pSounds[pNum];
-          if ( !pSoundDesc2->pSoundData[0] )
+          auto channel = pMixerChannels + i;
+
+          int volume = AIL_sample_volume(channel->hSample);
+          if (volume < min_volume)
           {
-            if (pSoundDesc2->eType == SOUND_DESC_SWAP)
-              pSoundList->LoadSound(eSoundID, 0);
+            min_volume = volume;
+            v62 = i;
           }
         }
-        v72 = 4 * (a7 + 30 * pNum) + 44;
-        if ( !*(int *)&pSoundList->pSounds->pSoundName[v72] )
-          return;
-        pMixerChannel5 = &pAudioPlayer->pMixerChannels[v62];
-        AIL_init_sample(pMixerChannel5->hSample);
-        AIL_set_sample_file(pMixerChannel5->hSample, (void *)(*(int *)&pSoundList->pSounds->pSoundName[v72] + 4 * (a7 == 0)), -1);
-        pVolume = uVolume;
-        if ( !uVolume )
-          pVolume = LODWORD(v93);
-        AIL_set_sample_volume(pMixerChannel5->hSample, pVolume);
-        pPartyX = PartyX;
-        if ( PartyX != -1 )
-        {
-          if ( !PartyX )
-            pPartyX = pParty->vPosition.x;
-          if ( !PartyY )
-            PartyY = pParty->vPosition.y;
-          if ( uNumRepeats )
-            AIL_set_sample_loop_count(pMixerChannel5->hSample, uNumRepeats - 1);
-          v83 = sub_4AB66C(pPartyX, PartyY);
-          AIL_set_sample_pan(pMixerChannel5->hSample, v83);
-          v84 = GetSoundStrengthByDistanceFromParty(pPartyX, PartyY, pParty->vPosition.z);
-          AIL_set_sample_volume(pMixerChannel5->hSample, v84);
-          v76 = a3;
-          goto LABEL_184;
-        }
-        v76 = a3;
-        if ( (a3 & 7) == 1 )
-        {
-          if ( uCurrentlyLoadedLevelType != LEVEL_Indoor )
-            goto LABEL_184;
-          pBLVDoor2 = &pIndoor->pDoors[a3 >> 3];
-          if ( !pBLVDoor2->uDoorID )
-            return;
-          if ( !GetSoundStrengthByDistanceFromParty(*pBLVDoor2->pXOffsets, *pBLVDoor2->pYOffsets, *pBLVDoor2->pZOffsets) )
-          {
-            AIL_end_sample(pMixerChannel5->hSample);
-            pAudioPlayer->AudioPlayer::_4ABE55(pMixerChannel5);
-            return;
-          }
-          pPosY = *pBLVDoor2->pYOffsets;
-          pPosX = *pBLVDoor2->pXOffsets;
-          //goto LABEL_167;
-		  v80 = sub_4AB66C(pPosX, pPosY);
-          AIL_set_sample_pan(pMixerChannel5->hSample, v80);
-          goto LABEL_184;
-        }
-        if ( (a3 & 7) == 2 )
-        {
-          pLayingItem4 = &pLayingItems[a3 >> 3];
-          if ( !GetSoundStrengthByDistanceFromParty(pLayingItem4->vPosition.x, pLayingItem4->vPosition.y, pLayingItem4->vPosition.z) )
-            return;
-        }
-        else
-        {
-          if ( (a3 & 7) == 3 )
-          {
-            pActor3 = &pActors[a3 >> 3];
-            if ( !GetSoundStrengthByDistanceFromParty(pActor3->vPosition.x, pActor3->vPosition.y, pActor3->vPosition.z) )
-              return;
-            pPosY = pActor3->vPosition.y;
-            pPosX = pActor3->vPosition.x;
-            //goto LABEL_167;
-			v80 = sub_4AB66C(pPosX, pPosY);
-            AIL_set_sample_pan(pMixerChannel5->hSample, v80);
-			goto LABEL_184;
-          }
-          if ( (a3 & 7) != 5 )
-          {
-LABEL_184:
-            if ( uNumRepeats )
-              AIL_set_sample_loop_count(pMixerChannel5->hSample, uNumRepeats - 1);
-            v85 = pMixerChannel5->hSample;
-            pMixerChannel5->uSourceTrackIdx = pNum;
-            pMixerChannel5->source_pid = v76;
-            pMixerChannel5->uSourceTrackID = eSoundID;
-            AIL_start_sample(v85);
-            if ( sPlaybackRate )
-              AIL_set_sample_playback_rate(pMixerChannel5->hSample, sPlaybackRate);
-            if ( (v76 & 7) == 4 )
-              AIL_sample_ms_position(pMixerChannel5->hSample, &sLastTrackLengthMS, 0);
-            return;
-          }
-          pLayingItem4 = (LayingItem *)&pLevelDecorations[a3 >> 3];
-          if ( !GetSoundStrengthByDistanceFromParty(pLayingItem4->vPosition.x, pLayingItem4->vPosition.y, pLayingItem4->vPosition.z) )
-            return;
-          AIL_set_sample_loop_count(pMixerChannel5->hSample, uNumRepeats - 1);
-        }
-        pPosY = pLayingItem4->vPosition.y;
-        pPosX = pLayingItem4->vPosition.x;
-//LABEL_167:
-        v80 = sub_4AB66C(pPosX, pPosY);
-        AIL_set_sample_pan(pMixerChannel5->hSample, v80);
-        goto LABEL_184;
-      }
-      v65 = varC;
-      v62 = -1;
-      v91 = v93;
-      if ( varC <= v96 )
+        /*v65 = start_channel;
+        v91 = v93;
+      if (start_channel <= end_channel)
       {
         //pAudioPlayer5 = pAudioPlayer;
-        pMixerChannel3 = &pAudioPlayer->pMixerChannels[varC];
+        pMixerChannel3 = &pAudioPlayer->pMixerChannels[start_channel];
         do
         {
           v68 = AIL_sample_volume(pMixerChannel3->hSample);
@@ -941,73 +936,120 @@
           ++v65;
           ++pMixerChannel3;
         }
-        while ( v65 <= v96 );
-        if ( v62 != -1 )
+        while ( v65 <= end_channel );*/
+
+        if (v62 == -1)   // no free channels at all - only channel 13 allows override (a3 == -1)
         {
-//LABEL_149:
-          //pAudioPlayer4 = pAudioPlayer;
-          pMixerChannel4 = &pAudioPlayer->pMixerChannels[v62];
-          AIL_end_sample(pMixerChannel4->hSample);
-          _4ABE55(pMixerChannel4);
-          goto LABEL_150;
+          if (start_channel != 13)
+            return;
+          v62 = 13;
         }
-        v65 = varC;
+
+        auto channel = &pMixerChannels[v62];
+        AIL_end_sample(channel->hSample);
+        _4ABE55(channel);
       }
-      v62 = 13;
-      if ( v65 != 13 )
+
+      if (v62 > end_channel)//10!=13
         return;
-      //goto LABEL_149;
-	  //pAudioPlayer4 = pAudioPlayer;
-      pMixerChannel4 = &pAudioPlayer->pMixerChannels[v62];
-      AIL_end_sample(pMixerChannel4->hSample);
-      _4ABE55(pMixerChannel4);
-      goto LABEL_150;
-    }
-    if ( (a3 & 7) == 2 )
-    {
-      varC = 5;
-      v96 = 7;
-      pLayingItem3 = &pLayingItems[a3 >> 3];
-    }
-    else
-    {
-      if ( (a3 & 7) == 3 )
+
+//LABEL_150:
+      if (sample_volume == 10000)
+        sample_volume = uMasterVolume;
+
+        //v70 = 0;
+      if ( !a7 )
+      {
+          //pSoundDesc = pSoundList->pSounds;
+          //pSoundDesc2 = &pSoundList->pSounds[sound_id];
+        if (!sound_desc->pSoundData[0])
+        {
+          if (sound_desc->eType == SOUND_DESC_SWAP)
+            pSoundList->LoadSound(eSoundID, 0);
+        }
+      }
+        //v72 = 4 * (a7 + 30 * sound_id) + 44;
+      if (!pSoundList->pSounds[sound_id].pSoundData[a7])
+        return;
+
+        //pMixerChannel5 = &pAudioPlayer->pMixerChannels[v62];
+      auto channel = &pMixerChannels[v62];
+      AIL_init_sample(channel->hSample);
+      AIL_set_sample_file(channel->hSample, (char *)pSoundList->pSounds[sound_id].pSoundData[a7] + 4 * (a7 == 0), -1);
+      int s = AIL_sample_status(channel->hSample);
+      if (uVolume)
+        sample_volume = uVolume;
+      AIL_set_sample_volume(channel->hSample, sample_volume);
+
+      int object_type = a3 & 7,
+          object_id = a3 >> 7;
+      if (PartyX != -1)
+      {
+        if (!PartyX) PartyX = pParty->vPosition.x;
+        if (!PartyY) PartyY = pParty->vPosition.y;
+        AIL_set_sample_pan(channel->hSample, sub_4AB66C(PartyX, PartyY));
+        AIL_set_sample_volume(channel->hSample, GetSoundStrengthByDistanceFromParty(PartyX, PartyY, pParty->vPosition.z));
+      }
+      else if (object_type == OBJECT_BLVDoor)
       {
-        *(float *)&varC = 0.0;
-        pActor2 = &pActors[a3 >> 3];
-        v96 = 3;
-        v58 = pActor2->vPosition.y;
-        v87 = pActor2->vPosition.z;
-        v59 = pActor2->vPosition.x;
-LABEL_116:
-        LODWORD(v93) = GetSoundStrengthByDistanceFromParty(v59, /*(int)pSoundDesc*/ v58, v87);
-        if ( v93 == 0.0 )
+        assert(uCurrentlyLoadedLevelType == LEVEL_Indoor);
+
+        assert(object_id < pIndoor->uNumDoors);
+        auto door = &pIndoor->pDoors[object_id];
+        if (!door->uDoorID)
           return;
-        goto LABEL_123;
-      }
-      if ( (a3 & 7) != 5 )
-      {
-        if ( (a3 & 7) == 6 )
+
+        if (!GetSoundStrengthByDistanceFromParty(door->pXOffsets[0], door->pYOffsets[0], door->pZOffsets[0]))
         {
-          varC = 8;
-          v96 = 9;
+          AIL_end_sample(channel->hSample);
+          _4ABE55(channel);
+          return;
         }
-        else
-        {
-          varC = 10;
-          v96 = 12;
-        }
-        goto LABEL_123;
+        AIL_set_sample_pan(channel->hSample, sub_4AB66C(door->pXOffsets[0], door->pYOffsets[0]));
+      }
+      else if (object_type == OBJECT_Item)
+      {
+        assert(object_id < uNumLayingItems);
+        auto object = &pLayingItems[object_id];
+        if (!GetSoundStrengthByDistanceFromParty(object->vPosition.x, object->vPosition.y, object->vPosition.z) )
+            return;
+        AIL_set_sample_pan(channel->hSample, sub_4AB66C(object->vPosition.x, object->vPosition.y));
+      }
+      else if (object_type == OBJECT_Actor)
+      {
+        assert(object_id < uNumActors);
+        auto actor = &pActors[object_id];
+        if (!GetSoundStrengthByDistanceFromParty(actor->vPosition.x, actor->vPosition.y, actor->vPosition.z))
+          return;
+        AIL_set_sample_pan(channel->hSample, sub_4AB66C(actor->vPosition.x, actor->vPosition.y));
       }
-      varC = 4;
-      v96 = 4;
-      pLayingItem3 = (LayingItem *)&pLevelDecorations[a3 >> 3];
-    }
-    v87 = pLayingItem3->vPosition.z;
-    v58 = pLayingItem3->vPosition.y;
-    v59 = pLayingItem3->vPosition.x;
-    goto LABEL_116;
+      else if (object_type == OBJECT_Decoration)
+      {
+        assert(object_id < uNumLevelDecorations);
+        auto decor = &pLevelDecorations[object_id];
+        if (!GetSoundStrengthByDistanceFromParty(decor->vPosition.x, decor->vPosition.y, decor->vPosition.z))
+          return;
+        AIL_set_sample_pan(channel->hSample, sub_4AB66C(decor->vPosition.x, decor->vPosition.y));
+      }
+
+//LABEL_184:
+      if (uNumRepeats)
+        AIL_set_sample_loop_count(channel->hSample, uNumRepeats - 1);
+      channel->uSourceTrackIdx = sound_id;
+      channel->source_pid = a3;
+      channel->uSourceTrackID = eSoundID;
+      int rval = AIL_start_sample(channel->hSample);
+      if ( sPlaybackRate )
+        AIL_set_sample_playback_rate(channel->hSample, sPlaybackRate);
+      if (object_type == OBJECT_Player)
+        AIL_sample_ms_position(channel->hSample, &sLastTrackLengthMS, 0);
+      return;
   }
+
+
+
+
+  __debugbreak(); // 3d sound stuff, refactor
   v12 = 13;
   if ( a3 < 0 )
   {
@@ -1143,7 +1185,7 @@
           if ( AIL_3D_sample_status(pAudioPlayer_3DSample->hSample) == 4 
 			  && pAudioPlayer_3DSample->field_4 == a3 && AIL_3D_sample_status(pAudioPlayer_3DSample->hSample) == 4 )
           {
-            if ( pAudioPlayer_3DSample->field_8 == pNum )
+            if ( pAudioPlayer_3DSample->field_8 == sound_id )
               return;
             AIL_end_3D_sample(pAudioPlayer_3DSample->hSample);
             pAudioPlayer->_4ABF23(pAudioPlayer_3DSample);
@@ -1227,12 +1269,12 @@
     pAudioPlayer->_4ABF23(pAudioPlayer_3DSample3);
     v102 = v36;
   }
-  v39 = v89;
-  if ( pSoundList->pSounds[v89 / 0x78].p3DSound || (LOWORD(v40) = pSoundList->LoadSound(eSoundID, 0), v40) )
+  //v39 = v89;
+  if ( pSoundList->pSounds[sound_id].p3DSound || (LOWORD(v40) = pSoundList->LoadSound(eSoundID, 0), v40) )
   {
     v41 = (char *)pAudioPlayer + 16 * v102;
     v42 = (int)(v41 + 20);
-    if ( AIL_set_3D_sample_file(*((int *)v41 + 5), *(void **)((char *)&pSoundList->pSounds->p3DSound + v39)) )
+    if ( AIL_set_3D_sample_file(*((int *)v41 + 5), *(void **)((char *)&pSoundList->pSounds->p3DSound + sound_id * sizeof(SoundDesc))) )
     {
       if ( uNumRepeats )
         v86 = uNumRepeats - 1;
@@ -1281,7 +1323,7 @@
             AIL_set_3D_orientation((void *)*(int *)v42, LODWORD(v54), 0.0, LODWORD(v53), 0.0, 1.0, 0.0);
             //pAudioPlayer3 = pAudioPlayer;
             *((int *)v41 + 6) = a3;
-            *((int *)v41 + 7) = pNum;
+            *((int *)v41 + 7) = sound_id;
             *(&pAudioPlayer->bEAXSupported + 4 * (v102 + 2)) = eSoundID;
           }
           else
--- a/AudioPlayer.h	Sat Feb 23 01:56:42 2013 +0400
+++ b/AudioPlayer.h	Sat Feb 23 04:02:05 2013 +0200
@@ -73,13 +73,14 @@
 /*  308 */
 enum SoundID
 {
-  SOUND_0 = 0,
+  SOUND_Invalid = 0,
   SOUND_EnteringAHouse = 0x6,
   SOUND_8 = 0x8,
   SOUND_27 = 0x1B,
   SOUND_Button = 66,
   SOUND_67 = 67,
   SOUND_71 = 71,
+  SOUND_Button2 = 75,
   SOUND_78 = 78,
   SOUND_80 = 80,
   SOUND_81 = 81,
@@ -236,6 +237,8 @@
 
 struct SoundDesc
 {
+  inline bool Is3D()  {return uFlags & SOUND_DESC_3D;}
+
   char pSoundName[32];
   unsigned int uSoundID;
   SOUND_DESC_TYPE eType;
--- a/VideoPlayer.cpp	Sat Feb 23 01:56:42 2013 +0400
+++ b/VideoPlayer.cpp	Sat Feb 23 04:02:05 2013 +0200
@@ -1125,7 +1125,7 @@
     pParty->uFlags &= 0xFFFFFFFDu;
     if ( EnterHouse((enum HOUSE_TYPE)165) )
     {
-      pAudioPlayer->PlaySound(SOUND_0, 0, 0, -1, 0, 0, 0, 0);
+      pAudioPlayer->PlaySound(SOUND_Invalid, 0, 0, -1, 0, 0, 0, 0);
       window_SpeakInHouse = GUIWindow::Create(0, 0, 640, 480, WINDOW_HouseInterior, 165, 0);
       window_SpeakInHouse->CreateButton(0x3Du, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 1u, 0x31u, "", 0);
       window_SpeakInHouse->CreateButton(0xB1u, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 2u, 0x32u, "", 0);
--- a/mm7_5.cpp	Sat Feb 23 01:56:42 2013 +0400
+++ b/mm7_5.cpp	Sat Feb 23 04:02:05 2013 +0200
@@ -13869,7 +13869,7 @@
   }
   v2 = 1;
   v31 = 1;
-  pAudioPlayer->PlaySound((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
+  pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
 LABEL_15:
   dword_506568 = 0;
   pRenderer->DrawTextureTransparent(pViewport->uViewportX + 398, pViewport->uViewportY + 113, pTexture_506394);
@@ -13879,7 +13879,7 @@
     if ( dword_506568 != v2 )
     {
       v31 = v2;
-      pAudioPlayer->PlaySound((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
+      pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
     }
   }
   else
@@ -13903,7 +13903,7 @@
     if ( dword_506568 != 2 )
     {
       v31 = v2;
-      pAudioPlayer->PlaySound((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
+      pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
     }
   }
   else
@@ -13927,7 +13927,7 @@
     if ( dword_506568 != 3 )
     {
       v31 = v2;
-      pAudioPlayer->PlaySound((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
+      pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
     }
   }
   else
@@ -13951,7 +13951,7 @@
     if ( dword_506568 != 4 )
     {
       v31 = v2;
-      pAudioPlayer->PlaySound((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
+      pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
     }
   }
   else
@@ -13975,7 +13975,7 @@
     if ( dword_506568 != 5 )
     {
       v31 = v2;
-      pAudioPlayer->PlaySound((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
+      pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
     }
   }
   else
@@ -14211,7 +14211,7 @@
     //v6 = dword_506534;
   }
   if ( dword_506548 | dword_506544 | dword_506540 | dword_50653C | dword_506538 | dword_506534 )
-    pAudioPlayer->PlaySound((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
+    pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
   dword_506548 = 0;
   dword_506544 = 0;
   dword_506534 = 0;
@@ -15080,7 +15080,7 @@
       case WINDOW_5E: // window that initiates savegame loading
       {
         if (pWindow->Hint != (char *)1)
-          pAudioPlayer->PlaySound((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
+          pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
         auto pGUIButton3 = (GUIButton *)pWindow->ptr_1C;
         pRenderer->DrawTextureIndexed(pWindow->uFrameX, pWindow->uFrameY, pGUIButton3->pTextures[0]);
         pHint = pWindow->Hint;
@@ -15103,7 +15103,7 @@
         if ( pWindowType == WINDOW_60 )//96
         {
           if ( pWindow->Hint != (char *)1 )
-            pAudioPlayer->PlaySound((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
+            pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
           pGUIButton = (GUIButton *)pWindow->ptr_1C;
           pRenderer->DrawTextureIndexed(pWindow->uFrameX, pWindow->uFrameY, pGUIButton->pTextures[0]);
           pHint = pWindow->Hint;
@@ -15184,7 +15184,7 @@
           GUIButton2.uWidth = 171;
           GUIButton2.uHeight = 37;
           GUIButton2.pParent = pButton_RestUI_WaitUntilDawn->pParent;
-          pAudioPlayer->PlaySound((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
+          pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
           pRenderer->DrawTextureIndexed(pWindow->uFrameX, pWindow->uFrameY, *((Texture **)pWindow->ptr_1C + 15));
           viewparams->bRedrawGameUI = 1;
           GUIButton2.DrawLabel(pGlobalTXT_LocalizationStrings[183], pFontCreate, 0, 0);//Отдых и лечение 8 часов
@@ -15196,7 +15196,7 @@
           continue;
         }
         if ( pWindow->Hint != (char *)1 )//pWindowType == WINDOW_61
-          pAudioPlayer->PlaySound((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
+          pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
         v32 = pWindow->ptr_1C;
         pRenderer->DrawTextureIndexed(pWindow->uFrameX, pWindow->uFrameY, *((Texture **)v32 + 16));
         //goto LABEL_138;
@@ -15220,7 +15220,7 @@
       if ( pWindowType == WINDOW_5F )
       {
         if ( pWindow->Hint != (char *)1 )
-          pAudioPlayer->PlaySound((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
+          pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
         v32 = pWindow->ptr_1C;
         pRenderer->DrawTextureTransparent(pWindow->uFrameX, pWindow->uFrameY, *((Texture **)v32 + 15));
 //LABEL_138:
@@ -15286,7 +15286,7 @@
         if ( pWindowType == WINDOW_5A ) // Press buttons in title menu and in game, and escape in game
         {
           if ( pWindow->Hint != (char *)1 )
-            pAudioPlayer->PlaySound((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
+            pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
           pButtonPtr_1C = (GUIButton *)pWindow->ptr_1C;
           if ( pButtonPtr_1C->uX >= 0 )//if ( (pButtonPtr_1C->uX & 0x80000000u) == 0 )
           {
@@ -15337,7 +15337,7 @@
         if ( pWindowType == WINDOW_5B )//Change button in Character window
         {
           if ( pWindow->Hint != (char *)1 )
-            pAudioPlayer->PlaySound((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
+            pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
           pButtonPtr_1C = (GUIButton *)pWindow->ptr_1C;
           pTexture2 = pButtonPtr_1C->pTextures[1];
 //LABEL_94:
@@ -15362,7 +15362,7 @@
         if ( pWindowType == WINDOW_VoiceSwitcherButton ) // Change page in AutonotesBook
         {
           if ( pWindow->Hint != (char *)1 )
-            pAudioPlayer->PlaySound((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
+            pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
           pButtonPtr_1C = (GUIButton *)pWindow->ptr_1C;
           pRenderer->DrawTextureTransparent(pWindow->uFrameX, pWindow->uFrameY, pButtonPtr_1C->pTextures[0]);
           //goto LABEL_80;
@@ -15382,7 +15382,7 @@
         if ( pWindowType == WINDOW_5D )
         {
           if ( pWindow->Hint != (char *)1 )
-            pAudioPlayer->PlaySound((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
+            pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
           pRenderer->DrawTextureTransparent(pWindow->uFrameX, pWindow->uFrameY, *((Texture **)pWindow->ptr_1C + 16));
           viewparams->bRedrawGameUI = 1;
           //goto LABEL_134;
--- a/mm7_6.cpp	Sat Feb 23 01:56:42 2013 +0400
+++ b/mm7_6.cpp	Sat Feb 23 04:02:05 2013 +0200
@@ -8785,7 +8785,7 @@
 //----- (0042FBDD) --------------------------------------------------------
 void __cdecl sub_42FBDD()
 {
-  pAudioPlayer->PlaySound((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
+  pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
   pRenderer->DrawTextureTransparent(pBtn_YES->uX, pBtn_YES->uY, pBtn_YES->pTextures[0]);
   pRenderer->Present();
 }
@@ -8793,7 +8793,7 @@
 //----- (0042FC15) --------------------------------------------------------
 void __cdecl CloseWindowBackground()
 {
-  pAudioPlayer->PlaySound((SoundID)75, -2, 0, -1, 0, 0, 0, 0);
+  pAudioPlayer->PlaySound(SOUND_Button2, -2, 0, -1, 0, 0, 0, 0);
   pRenderer->DrawTextureTransparent(pBtn_ExitCancel->uX, pBtn_ExitCancel->uY, pBtn_ExitCancel->pTextures[0]);
   pRenderer->Present();
 }