(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
analyzer/
doom-s_sound-pr108867.c
       1  /* Reduced from Doom's linuxdoom-1.10/s_sound.c, which is GPLv2 or later.  */
       2  
       3  /* { dg-additional-options "-fno-analyzer-call-summaries -Wno-analyzer-too-complex" } */
       4  
       5  typedef struct _IO_FILE FILE;
       6  extern FILE* stderr;
       7  extern int
       8  fprintf(FILE* __restrict __stream, const char* __restrict __format, ...);
       9  extern int
      10  sprintf(char* __restrict __s, const char* __restrict __format, ...)
      11    __attribute__((__nothrow__));
      12  extern int
      13  abs(int __x) __attribute__((__nothrow__, __leaf__)) __attribute__((__const__));
      14  
      15  typedef enum
      16  {
      17    false,
      18    true
      19  } boolean;
      20  
      21  typedef unsigned char byte;
      22  
      23  void
      24  I_Error(char* error, ...);
      25  
      26  typedef enum
      27  {
      28    shareware,
      29    registered,
      30    commercial,
      31    /* [...snip...] */
      32  } GameMode_t;
      33  
      34  typedef int fixed_t;
      35  
      36  fixed_t
      37  FixedMul(fixed_t a, fixed_t b);
      38  
      39  extern fixed_t finesine[5 * 8192 / 4];
      40  typedef unsigned angle_t;
      41  
      42  typedef struct mobj_s
      43  {
      44    /* [...snip...] */
      45    fixed_t x;
      46    fixed_t y;
      47    fixed_t z;
      48    /* [...snip...] */
      49    angle_t angle;
      50    /* [...snip...] */
      51  } mobj_t;
      52  
      53  typedef struct player_s
      54  {
      55    mobj_t* mo;
      56    /* [...snip...] */
      57  } player_t;
      58  
      59  extern GameMode_t gamemode;
      60  extern int gameepisode;
      61  extern int gamemap;
      62  extern int consoleplayer;
      63  extern player_t players[4];
      64  
      65  typedef struct sfxinfo_struct sfxinfo_t;
      66  
      67  struct sfxinfo_struct
      68  {
      69    /* [...snip...] */
      70    int priority;
      71    sfxinfo_t* link;
      72    int pitch;
      73    int volume;
      74    void* data;
      75    int usefulness;
      76    int lumpnum;
      77  };
      78  
      79  typedef struct
      80  {
      81    char* name;
      82    int lumpnum;
      83    void* data;
      84    int handle;
      85  } musicinfo_t;
      86  
      87  extern sfxinfo_t S_sfx[];
      88  
      89  extern musicinfo_t S_music[];
      90  
      91  typedef enum
      92  {
      93    mus_None,
      94    mus_e1m1,
      95    /* [...snip...] */
      96    mus_e1m5,
      97    /* [...snip...] */
      98    mus_e1m9,
      99    /* [...snip...] */
     100    mus_e2m4,
     101    mus_e2m5,
     102    mus_e2m6,
     103    mus_e2m7,
     104    /* [...snip...] */
     105    mus_e3m2,
     106    mus_e3m3,
     107    mus_e3m4,
     108    /* [...snip...] */
     109    mus_runnin,
     110    /* [...snip...] */
     111    NUMMUSIC
     112  } musicenum_t;
     113  
     114  typedef enum
     115  {
     116    /* [...snip...] */
     117    sfx_sawup,
     118    /* [...snip...] */
     119    sfx_sawhit,
     120    /* [...snip...] */
     121    sfx_itemup,
     122    /* [...snip...] */
     123    sfx_tink,
     124    /* [...snip...] */
     125    NUMSFX
     126  } sfxenum_t;
     127  
     128  
     129  void
     130  I_SetChannels();
     131  
     132  int
     133  I_GetSfxLumpNum(sfxinfo_t* sfxinfo);
     134  
     135  int
     136  I_StartSound(int id, int vol, int sep, int pitch, int priority);
     137  
     138  void
     139  I_StopSound(int handle);
     140  int
     141  I_SoundIsPlaying(int handle);
     142  void
     143  I_UpdateSoundParams(int handle, int vol, int sep, int pitch);
     144  
     145  void
     146  I_SetMusicVolume(int volume);
     147  
     148  void
     149  I_PauseSong(int handle);
     150  void
     151  I_ResumeSong(int handle);
     152  int
     153  I_RegisterSong(void* data);
     154  
     155  void
     156  I_PlaySong(int handle, int looping);
     157  
     158  void
     159  I_StopSong(int handle);
     160  
     161  void
     162  I_UnRegisterSong(int handle);
     163  void
     164  S_StopSound(void* origin);
     165  void
     166  S_ChangeMusic(int music_id, int looping);
     167  void
     168  S_StopMusic(void);
     169  
     170  void
     171  S_SetMusicVolume(int volume);
     172  void
     173  S_SetSfxVolume(int volume);
     174  
     175  void*
     176  Z_Malloc(int size, int tag, void* ptr);
     177  void
     178  Z_ChangeTag2(void* ptr, int tag);
     179  
     180  typedef struct memblock_s
     181  {
     182    /* [...snip...] */
     183    int id;
     184    /* [...snip...] */
     185  } memblock_t;
     186  int
     187  M_Random(void);
     188  int
     189  W_GetNumForName(char* name);
     190  void*
     191  W_CacheLumpNum(int lump, int tag);
     192  angle_t
     193  R_PointToAngle2(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2);
     194  
     195  typedef struct
     196  {
     197    sfxinfo_t* sfxinfo;
     198    void* origin;
     199    int handle;
     200  } channel_t;
     201  static channel_t* channels;
     202  
     203  int snd_SfxVolume = 15;
     204  int snd_MusicVolume = 15;
     205  static boolean mus_paused;
     206  static musicinfo_t* mus_playing = 0;
     207  int numChannels;
     208  static int nextcleanup;
     209  
     210  int
     211  S_getChannel(void* origin, sfxinfo_t* sfxinfo);
     212  
     213  int
     214  S_AdjustSoundParams(mobj_t* listener,
     215                      mobj_t* source,
     216                      int* vol,
     217                      int* sep,
     218                      int* pitch);
     219  void
     220  S_StopChannel(int cnum);
     221  
     222  void
     223  S_Init(int sfxVolume, int musicVolume)
     224  {
     225    int i;
     226  
     227    fprintf(stderr, "S_Init: default sfx volume %d\n", sfxVolume);
     228  
     229    I_SetChannels();
     230  
     231    S_SetSfxVolume(sfxVolume);
     232  
     233    S_SetMusicVolume(musicVolume);
     234  
     235    channels = (channel_t*)Z_Malloc(numChannels * sizeof(channel_t), 1, 0);
     236  
     237    for (i = 0; i < numChannels; i++)
     238      channels[i].sfxinfo = 0;
     239  
     240    mus_paused = 0;
     241  
     242    for (i = 1; i < NUMSFX; i++)
     243      S_sfx[i].lumpnum = S_sfx[i].usefulness = -1;
     244  }
     245  void
     246  S_Start(void)
     247  {
     248    int cnum;
     249    int mnum;
     250  
     251    for (cnum = 0; cnum < numChannels; cnum++)
     252      if (channels[cnum].sfxinfo)
     253        S_StopChannel(cnum);
     254  
     255    mus_paused = 0;
     256  
     257    if (gamemode == commercial)
     258      mnum = mus_runnin + gamemap - 1;
     259    else {
     260      int spmus[] = {
     261  
     262        mus_e3m4, mus_e3m2, mus_e3m3, mus_e1m5, mus_e2m7,
     263        mus_e2m4, mus_e2m6, mus_e2m5, mus_e1m9
     264      };
     265  
     266      if (gameepisode < 4)
     267        mnum = mus_e1m1 + (gameepisode - 1) * 9 + gamemap - 1;
     268      else
     269        mnum = spmus[gamemap - 1];
     270    }
     271  
     272    S_ChangeMusic(mnum, true);
     273  
     274    nextcleanup = 15;
     275  }
     276  
     277  void
     278  S_StartSoundAtVolume(void* origin_p, int sfx_id, int volume)
     279  {
     280  
     281    int rc;
     282    int sep;
     283    int pitch;
     284    int priority;
     285    sfxinfo_t* sfx;
     286    int cnum;
     287  
     288    mobj_t* origin = (mobj_t*)origin_p;
     289    if (sfx_id < 1 || sfx_id > NUMSFX)
     290      I_Error("Bad sfx #: %d", sfx_id);
     291  
     292    sfx = &S_sfx[sfx_id];
     293  
     294    if (sfx->link) {
     295      pitch = sfx->pitch;
     296      priority = sfx->priority;
     297      volume += sfx->volume;
     298  
     299      if (volume < 1)
     300        return;
     301  
     302      if (volume > snd_SfxVolume)
     303        volume = snd_SfxVolume;
     304    } else {
     305      pitch = 128;
     306      priority = 64;
     307    }
     308  
     309    if (origin && origin != players[consoleplayer].mo) {
     310      rc = S_AdjustSoundParams(
     311        players[consoleplayer].mo, origin, &volume, &sep, &pitch);
     312  
     313      if (origin->x == players[consoleplayer].mo->x &&
     314          origin->y == players[consoleplayer].mo->y) {
     315        sep = 128;
     316      }
     317  
     318      if (!rc)
     319        return;
     320    } else {
     321      sep = 128;
     322    }
     323  
     324    if (sfx_id >= sfx_sawup && sfx_id <= sfx_sawhit) {
     325      pitch += 8 - (M_Random() & 15);
     326  
     327      if (pitch < 0)
     328        pitch = 0;
     329      else if (pitch > 255)
     330        pitch = 255;
     331    } else if (sfx_id != sfx_itemup && sfx_id != sfx_tink) {
     332      pitch += 16 - (M_Random() & 31);
     333  
     334      if (pitch < 0)
     335        pitch = 0;
     336      else if (pitch > 255)
     337        pitch = 255;
     338    }
     339  
     340    S_StopSound(origin);
     341  
     342    cnum = S_getChannel(origin, sfx);
     343  
     344    if (cnum < 0)
     345      return;
     346    if (sfx->lumpnum < 0)
     347      sfx->lumpnum = I_GetSfxLumpNum(sfx);
     348  
     349    if (!sfx->data) {
     350      fprintf(stderr, "S_StartSoundAtVolume: 16bit and not pre-cached - wtf?\n");
     351    }
     352  
     353    if (sfx->usefulness++ < 0)
     354      sfx->usefulness = 1;
     355  
     356    channels[cnum].handle = I_StartSound(sfx_id,
     357  
     358                                         volume,
     359                                         sep,
     360                                         pitch,
     361                                         priority);
     362  }
     363  
     364  void
     365  S_StartSound(void* origin, int sfx_id)
     366  {
     367  
     368    S_StartSoundAtVolume(origin, sfx_id, snd_SfxVolume);
     369  }
     370  
     371  void
     372  S_StopSound(void* origin)
     373  {
     374  
     375    int cnum;
     376  
     377    for (cnum = 0; cnum < numChannels; cnum++) {
     378      if (channels[cnum].sfxinfo && channels[cnum].origin == origin) {
     379        S_StopChannel(cnum);
     380        break;
     381      }
     382    }
     383  }
     384  void
     385  S_PauseSound(void)
     386  {
     387    if (mus_playing && !mus_paused) {
     388      I_PauseSong(mus_playing->handle);
     389      mus_paused = true;
     390    }
     391  }
     392  
     393  void
     394  S_ResumeSound(void)
     395  {
     396    if (mus_playing && mus_paused) {
     397      I_ResumeSong(mus_playing->handle);
     398      mus_paused = false;
     399    }
     400  }
     401  
     402  void
     403  S_UpdateSounds(void* listener_p)
     404  {
     405    int audible;
     406    int cnum;
     407    int volume;
     408    int sep;
     409    int pitch;
     410    sfxinfo_t* sfx;
     411    channel_t* c;
     412  
     413    mobj_t* listener = (mobj_t*)listener_p;
     414    for (cnum = 0; cnum < numChannels; cnum++) {
     415      c = &channels[cnum];
     416      sfx = c->sfxinfo;
     417  
     418      if (c->sfxinfo) {
     419        if (I_SoundIsPlaying(c->handle)) {
     420  
     421          volume = snd_SfxVolume;
     422          pitch = 128;
     423          sep = 128;
     424  
     425          if (sfx->link) {
     426            pitch = sfx->pitch;
     427            volume += sfx->volume;
     428            if (volume < 1) {
     429              S_StopChannel(cnum);
     430              continue;
     431            } else if (volume > snd_SfxVolume) {
     432              volume = snd_SfxVolume;
     433            }
     434          }
     435  
     436          if (c->origin && listener_p != c->origin) {
     437            audible =
     438              S_AdjustSoundParams(listener, c->origin, &volume, &sep, &pitch);
     439  
     440            if (!audible) {
     441              S_StopChannel(cnum);
     442            } else
     443              I_UpdateSoundParams(c->handle, volume, sep, pitch);
     444          }
     445        } else {
     446  
     447          S_StopChannel(cnum);
     448        }
     449      }
     450    }
     451  }
     452  
     453  void
     454  S_SetMusicVolume(int volume)
     455  {
     456    if (volume < 0 || volume > 127) {
     457      I_Error("Attempt to set music volume at %d", volume);
     458    }
     459  
     460    I_SetMusicVolume(127);
     461    I_SetMusicVolume(volume);
     462    snd_MusicVolume = volume;
     463  }
     464  
     465  void
     466  S_SetSfxVolume(int volume)
     467  {
     468  
     469    if (volume < 0 || volume > 127)
     470      I_Error("Attempt to set sfx volume at %d", volume);
     471  
     472    snd_SfxVolume = volume;
     473  }
     474  
     475  void
     476  S_StartMusic(int m_id)
     477  {
     478    S_ChangeMusic(m_id, false);
     479  }
     480  
     481  void
     482  S_ChangeMusic(int musicnum, int looping)
     483  {
     484    musicinfo_t* music;
     485    char namebuf[9];
     486  
     487    if ((musicnum <= mus_None) || (musicnum >= NUMMUSIC)) {
     488      I_Error("Bad music number %d", musicnum);
     489    } else
     490      music = &S_music[musicnum];
     491  
     492    /* We don't know that I_Error exits, so actually a false positive;
     493       see PR analyzer/108867.  */
     494  
     495    if (mus_playing == music) /* { dg-warning "use of uninitialized value 'music'" } */
     496      return;
     497  
     498    S_StopMusic();
     499  
     500    /* We shouldn't issue further warnings about 'music' being
     501       uninitialized.  */
     502  
     503    if (!music->lumpnum) { /* { dg-bogus "use of uninitialized value 'music'" } */
     504      sprintf(namebuf, "d_%s", music->name); /* { dg-bogus "use of uninitialized value 'music'" } */
     505      music->lumpnum = W_GetNumForName(namebuf); /* { dg-bogus "use of uninitialized value 'music'" } */
     506    }
     507  
     508    music->data = (void*)W_CacheLumpNum(music->lumpnum, 3); /* { dg-bogus "use of uninitialized value 'music'" } */
     509    music->handle = I_RegisterSong(music->data); /* { dg-bogus "use of uninitialized value 'music'" } */
     510  
     511    I_PlaySong(music->handle, looping); /* { dg-bogus "use of uninitialized value 'music'" } */
     512  
     513    mus_playing = music; /* { dg-bogus "use of uninitialized value 'music'" } */
     514  }
     515  
     516  void
     517  S_StopMusic(void)
     518  {
     519    if (mus_playing) {
     520      if (mus_paused)
     521        I_ResumeSong(mus_playing->handle);
     522  
     523      I_StopSong(mus_playing->handle);
     524      I_UnRegisterSong(mus_playing->handle);
     525      {
     526        if (((memblock_t*)((byte*)(mus_playing->data) - sizeof(memblock_t)))
     527              ->id != 0x1d4a11)
     528          I_Error("Z_CT at "
     529                  "s_sound.c"
     530                  ":%i",
     531                  699);
     532        Z_ChangeTag2(mus_playing->data, 101);
     533      };
     534      ;
     535  
     536      mus_playing->data = 0;
     537      mus_playing = 0;
     538    }
     539  }
     540  
     541  void
     542  S_StopChannel(int cnum)
     543  {
     544  
     545    int i;
     546    channel_t* c = &channels[cnum];
     547  
     548    if (c->sfxinfo) {
     549  
     550      if (I_SoundIsPlaying(c->handle)) {
     551  
     552        I_StopSound(c->handle);
     553      }
     554  
     555      for (i = 0; i < numChannels; i++) {
     556        if (cnum != i && c->sfxinfo == channels[i].sfxinfo) {
     557          break;
     558        }
     559      }
     560  
     561      c->sfxinfo->usefulness--;
     562  
     563      c->sfxinfo = 0;
     564    }
     565  }
     566  int
     567  S_AdjustSoundParams(mobj_t* listener,
     568                      mobj_t* source,
     569                      int* vol,
     570                      int* sep,
     571                      int* pitch)
     572  {
     573    fixed_t approx_dist;
     574    fixed_t adx;
     575    fixed_t ady;
     576    angle_t angle;
     577  
     578    adx = abs(listener->x - source->x);
     579    ady = abs(listener->y - source->y);
     580  
     581    approx_dist = adx + ady - ((adx < ady ? adx : ady) >> 1);
     582  
     583    if (gamemap != 8 && approx_dist > (1200 * 0x10000)) {
     584      return 0;
     585    }
     586  
     587    angle = R_PointToAngle2(listener->x, listener->y, source->x, source->y);
     588  
     589    if (angle > listener->angle)
     590      angle = angle - listener->angle;
     591    else
     592      angle = angle + (0xffffffff - listener->angle);
     593  
     594    angle >>= 19;
     595  
     596    *sep = 128 - (FixedMul((96 * 0x10000), finesine[angle]) >> 16);
     597  
     598    if (approx_dist < (160 * 0x10000)) {
     599      *vol = snd_SfxVolume;
     600    } else if (gamemap == 8) {
     601      if (approx_dist > (1200 * 0x10000))
     602        approx_dist = (1200 * 0x10000);
     603  
     604      *vol =
     605        15 + ((snd_SfxVolume - 15) * (((1200 * 0x10000) - approx_dist) >> 16)) /
     606               (((1200 * 0x10000) - (160 * 0x10000)) >> 16);
     607    } else {
     608  
     609      *vol = (snd_SfxVolume * (((1200 * 0x10000) - approx_dist) >> 16)) /
     610             (((1200 * 0x10000) - (160 * 0x10000)) >> 16);
     611    }
     612  
     613    return (*vol > 0);
     614  }
     615  int
     616  S_getChannel(void* origin, sfxinfo_t* sfxinfo)
     617  {
     618  
     619    int cnum;
     620  
     621    channel_t* c;
     622  
     623    for (cnum = 0; cnum < numChannels; cnum++) {
     624      if (!channels[cnum].sfxinfo)
     625        break;
     626      else if (origin && channels[cnum].origin == origin) {
     627        S_StopChannel(cnum);
     628        break;
     629      }
     630    }
     631  
     632    if (cnum == numChannels) {
     633  
     634      for (cnum = 0; cnum < numChannels; cnum++)
     635        if (channels[cnum].sfxinfo->priority >= sfxinfo->priority) /* { dg-warning "dereference of NULL" } */
     636          break;
     637  
     638      if (cnum == numChannels) {
     639  
     640        return -1;
     641      } else {
     642  
     643        S_StopChannel(cnum);
     644      }
     645    }
     646  
     647    c = &channels[cnum];
     648  
     649    c->sfxinfo = sfxinfo;
     650    c->origin = origin;
     651  
     652    return cnum;
     653  }