code:
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors

This file is part of EDuke32.

EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
//-------------------------------------------------------------------------

#ifndef sector_h_
#define sector_h_

#include "actors.h"  // actor_t
#include "gamevars.h"
#include "macros.h"
#include "namesdyn.h"  // for G_GetForcefieldPicnum()
#include "player.h"  // playerspawn_t

#ifdef __cplusplus
extern "C" {
#endif

#define MAXCYCLERS      1024
#define MAXANIMATES     1024
#define MAXANIMWALLS    512
#define MAXANIMPOINTS   2048

#define VIEWSCREEN_ACTIVE_DISTANCE 8192

extern uint8_t g_shadedSector[MAXSECTORS];

typedef struct {
    int16_t wallnum, tag;
} animwalltype;

typedef struct {
    // this needs to have a copy of everything related to the map/actor state
    // see savegame.c
    int32_t g_animateGoal[MAXANIMATES], g_animateVel[MAXANIMATES], g_animateCnt;
    intptr_t g_animatePtr[MAXANIMATES];
    int32_t lockclock;
    vec2_t origins[MAXANIMPOINTS];
    int32_t randomseed, g_globalRandom;
    int32_t pskyidx;

    int16_t SpriteDeletionQueue[1024],g_spriteDeleteQueuePos;
    int16_t g_animateSect[MAXANIMATES];
    int16_t g_cyclers[MAXCYCLERS][6];
    int16_t g_mirrorWall[64], g_mirrorSector[64], g_mirrorCount;
    int16_t g_animWallCnt;
    int16_t g_cloudCnt,g_cloudSect[256],g_cloudX,g_cloudY;
    int16_t g_cyclerCnt;

    int32_t numsprites;
    int16_t tailspritefree;
    int16_t headspritesect[MAXSECTORS+1];
    int16_t headspritestat[MAXSTATUS+1];
    int16_t nextspritesect[MAXSPRITES];
    int16_t nextspritestat[MAXSPRITES];
    int16_t numsectors;
    int16_t numwalls;
    int16_t prevspritesect[MAXSPRITES];
    int16_t prevspritestat[MAXSPRITES];

    uint16_t g_earthquakeTime;
    int8_t g_playerSpawnCnt;

    uint8_t show2dsector[(MAXSECTORS+7)>>3];

    actor_t actor[MAXSPRITES];
    playerspawn_t g_playerSpawnPoints[MAXPLAYERS];
    animwalltype animwall[MAXANIMWALLS];
    usectortype sector[MAXSECTORS];
    spriteext_t spriteext[MAXSPRITES];
    uspritetype sprite[MAXSPRITES];
    uwalltype wall[MAXWALLS];
#ifndef NEW_MAP_FORMAT
    wallext_t wallext[MAXWALLS];
#endif
    intptr_t *vars[MAXGAMEVARS];
#ifdef YAX_ENABLE
    int32_t numyaxbunches;
# if !defined NEW_MAP_FORMAT
    int16_t yax_bunchnum[MAXSECTORS][2];
    int16_t yax_nextwall[MAXWALLS][2];
# endif
#endif
} mapstate_t;

typedef struct {
    int32_t partime, designertime;
    char *name, *filename, *musicfn;
    mapstate_t *savedstate;
} map_t;

//extern map_t g_mapInfo[(MAXVOLUMES+1)*MAXLEVELS]; // +1 volume for "intro", "briefing" music

void G_ActivateBySector(int sect,int spriteNum);
int S_FindMusicSFX(int sectNum, int *sndptr);
void A_CallSound2(int soundNum, int playerNum);
int A_CallSound(int sectNum,int spriteNum);
int A_CheckHitSprite(int spriteNum,int16_t *hitSprite);
void A_DamageObject(int spriteNum,int dmgSrc);
void A_DamageWall(int spr,int dawallnum,const vec3_t *pos,int weaponNum);
int __fastcall A_FindPlayer(const spritetype *pSprite,int32_t *dist);
void G_AlignWarpElevators(void);
int CheckDoorTile(int tileNum);
int CheckBlockDoorTile(int tileNum);
void G_AnimateCamSprite(int smoothRatio);
void G_AnimateWalls(void);
int G_ActivateWarpElevators(int s,int warpDir);
int G_CheckActivatorMotion(int lotag);
void G_DoSectorAnimations(void);
void G_OperateActivators(int lotag, int playerNum);
void G_OperateForceFields(int spriteNum,int wallTag);
void G_OperateMasterSwitches(int lotag);
void G_OperateRespawns(int lotag);
void G_OperateSectors(int sectNum,int spriteNum);
void P_HandleSharedKeys(int playerNum);
int GetAnimationGoal(const int32_t *animPtr);
int isanearoperator(int lotag);
int isanunderoperator(int lotag);
int P_ActivateSwitch(int playerNum, int wallOrSprite, int nSwitchType);
void P_CheckSectors(int playerNum);
void Sect_DamageCeiling(int sectNum);
int SetAnimation(int sectNum,int32_t *animPtr,int goalVal,int animVel);
void G_DoFurniture(int wallNum, int sectNum, int playerNum);
void G_DoTorch(void);
void G_DoJailDoor(void);
void G_MoveMineCart(void);
void G_Thunder(void);

#define FORCEFIELD_CSTAT (64+16+4+1)

// Returns W_FORCEFIELD if wall has a forcefield overpicnum, its overpicnum else.
static inline int G_GetForcefieldPicnum(int wallNum)
{
    int tileNum = wall[wallNum].overpicnum;
    if (tileNum == W_FORCEFIELD + 1 || tileNum == W_FORCEFIELD + 2)
        tileNum = W_FORCEFIELD;
    return tileNum;
}

// Returns the interpolated position of the camera that the player is looking
// through (using a viewscreen). <i> should be the player's ->newowner member.
static inline vec3_t G_GetCameraPosition(int32_t i, int32_t smoothratio)
{
    const spritetype *const cs = &sprite[i];
    const actor_t *const ca = &actor[i];

    vec3_t cam = { ca->bpos.x + mulscale16(cs->x - ca->bpos.x, smoothratio),
                   ca->bpos.y + mulscale16(cs->y - ca->bpos.y, smoothratio),
                   ca->bpos.z + mulscale16(cs->z - ca->bpos.z, smoothratio)
                 };
    return cam;
}

EXTERN_INLINE_HEADER int32_t G_CheckPlayerInSector(int32_t sect);

#ifdef __cplusplus
}
#endif

#if defined sector_c_ || !defined DISABLE_INLINING

EXTERN_INLINE int32_t G_CheckPlayerInSector(int32_t sect)
{
    int32_t i;
    for (TRAVERSE_CONNECT(i))
        if ((unsigned)g_player[i].ps->i < MAXSPRITES && sprite[g_player[i].ps->i].sectnum == sect)
            return i;
    return -1;
}

#endif

#endif

repo_name: orochi/nblood

license: mit


code:
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors

This file is part of EDuke32.

EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
//-------------------------------------------------------------------------

#define KICK_HIT                         0
#define PISTOL_RICOCHET                  1
#define PISTOL_BODYHIT                   2
#define PISTOL_FIRE                      3
#define EJECT_CLIP                       4
#define INSERT_CLIP                      5
#define CHAINGUN_FIRE                    6
#define RPG_SHOOT                        7
#define POOLBALLHIT                      8
#define RPG_EXPLODE                      9
#define CAT_FIRE                        10
#define SHRINKER_FIRE                   11
#define ACTOR_SHRINKING                 12
#define PIPEBOMB_BOUNCE                 13
#define PIPEBOMB_EXPLODE                14
#define LASERTRIP_ONWALL                15
#define LASERTRIP_ARMING                16
#define LASERTRIP_EXPLODE               17
#define VENT_BUST                       18
#define GLASS_BREAKING                  19
#define GLASS_HEAVYBREAK                20
#define SHORT_CIRCUIT                   21
#define ITEM_SPLASH                     22
#define DUKE_BREATHING                  23
#define DUKE_EXHALING                   24
#define DUKE_GASP                       25
#define SLIM_RECOG                      26
// #define ENDSEQVOL3SND1                  27
#define DUKE_URINATE                    28
#define ENDSEQVOL3SND2                  29
#define ENDSEQVOL3SND3                  30
#define DUKE_PASSWIND                   32
#define DUKE_CRACK                      33
#define SLIM_ATTACK                     34
#define SOMETHINGHITFORCE               35
#define DUKE_DRINKING                   36
#define DUKE_KILLED1                    37
#define DUKE_GRUNT                      38
#define DUKE_HARTBEAT                   39
#define DUKE_ONWATER                    40
#define DUKE_DEAD                       41
#define DUKE_LAND                       42
#define DUKE_WALKINDUCTS                43
#define DUKE_GLAD                       44
#define DUKE_YES                        45
#define DUKE_HEHE                       46
#define DUKE_SHUCKS                     47
#define DUKE_UNDERWATER                 48
#define DUKE_JETPACK_ON                 49
#define DUKE_JETPACK_IDLE               50
#define DUKE_JETPACK_OFF                51
#define LIZTROOP_GROWL                  52
#define LIZTROOP_TALK1                  53
#define LIZTROOP_TALK2                  54
#define LIZTROOP_TALK3                  55
#define DUKETALKTOBOSS                  56
#define LIZCAPT_GROWL                   57
#define LIZCAPT_TALK1                   58
#define LIZCAPT_TALK2                   59
#define LIZCAPT_TALK3                   60
#define LIZARD_BEG                      61
#define LIZARD_PAIN                     62
#define LIZARD_DEATH                    63
#define LIZARD_SPIT                     64
#define DRONE1_HISSRATTLE               65
#define DRONE1_HISSSCREECH              66
#define DUKE_TIP2                       67
#define FLESH_BURNING                   68
#define SQUISHED                        69
#define TELEPORTER                      70
#define ELEVATOR_ON                     71
#define DUKE_KILLED3                    72
#define ELEVATOR_OFF                    73
#define DOOR_OPERATE1                   74
#define SUBWAY                          75
#define SWITCH_ON                       76
#define FAN                             77
#define DUKE_GETWEAPON3                 78
#define FLUSH_TOILET                    79
#define HOVER_CRAFT                     80
#define EARTHQUAKE                      81
#define INTRUDER_ALERT                  82
#define END_OF_LEVEL_WARN               83
#define ENGINE_OPERATING                84
#define REACTOR_ON                      85
#define COMPUTER_AMBIENCE               86
#define GEARS_GRINDING                  87
#define BUBBLE_AMBIENCE                 88
#define MACHINE_AMBIENCE                89
#define SEWER_AMBIENCE                  90
#define WIND_AMBIENCE                   91
#define SOMETHING_DRIPPING              92
#define STEAM_HISSING                   93
#define THEATER_BREATH                  94
#define BAR_MUSIC                       95
#define BOS1_ROAM                       96
#define BOS1_RECOG                      97
#define BOS1_ATTACK1                    98
#define BOS1_PAIN                       99
#define BOS1_DYING                     100
#define BOS2_ROAM                      101
#define BOS2_RECOG                     102
#define BOS2_ATTACK                    103
#define BOS2_PAIN                      104
#define BOS2_DYING                     105
#define GETATOMICHEALTH                106
#define DUKE_GETWEAPON2                107
#define BOS3_DYING                     108
#define SHOTGUN_FIRE                   109
#define PRED_ROAM                      110
#define PRED_RECOG                     111
#define PRED_ATTACK                    112
#define PRED_PAIN                      113
#define PRED_DYING                     114
#define CAPT_ROAM                      115
#define CAPT_ATTACK                    116
#define CAPT_RECOG                     117
#define CAPT_PAIN                      118
#define CAPT_DYING                     119
#define PIG_ROAM                       120
#define PIG_RECOG                      121
#define PIG_ATTACK                     122
#define PIG_PAIN                       123
#define PIG_DYING                      124
#define RECO_ROAM                      125
#define RECO_RECOG                     126
#define RECO_ATTACK                    127
#define RECO_PAIN                      128
#define RECO_DYING                     129
#define DRON_ROAM                      130
#define DRON_RECOG                     131
#define DRON_ATTACK1                   132
#define DRON_PAIN                      133
#define DRON_DYING                     134
#define COMM_ROAM                      135
#define COMM_RECOG                     136
#define COMM_ATTACK                    137
#define COMM_PAIN                      138
#define COMM_DYING                     139
#define OCTA_ROAM                      140
#define OCTA_RECOG                     141
#define OCTA_ATTACK1                   142
#define OCTA_PAIN                      143
#define OCTA_DYING                     144
#define TURR_ROAM                      145
#define TURR_RECOG                     146
#define TURR_ATTACK                    147
#define DUMPSTER_MOVE                  148
#define SLIM_DYING                     149
#define BOS3_ROAM                      150
#define BOS3_RECOG                     151
#define BOS3_ATTACK1                   152
#define BOS3_PAIN                      153
#define BOS1_ATTACK2                   154
#define COMM_SPIN                      155
#define BOS1_WALK                      156
#define DRON_ATTACK2                   157
#define THUD                           158
#define OCTA_ATTACK2                   159
#define WIERDSHOT_FLY                  160
#define TURR_PAIN                      161
#define TURR_DYING                     162
#define SLIM_ROAM                      163
#define LADY_SCREAM                    164
#define DOOR_OPERATE2                  165
#define DOOR_OPERATE3                  166
#define DOOR_OPERATE4                  167
#define BORNTOBEWILDSND                168
#define SHOTGUN_COCK                   169
#define GENERIC_AMBIENCE1              170
#define GENERIC_AMBIENCE2              171
#define GENERIC_AMBIENCE3              172
#define GENERIC_AMBIENCE4              173
#define GENERIC_AMBIENCE5              174
#define GENERIC_AMBIENCE6              175
#define BOS3_ATTACK2                   176
#define GENERIC_AMBIENCE17             177
#define GENERIC_AMBIENCE18             178
#define GENERIC_AMBIENCE19             179
#define GENERIC_AMBIENCE20             180
#define GENERIC_AMBIENCE21             181
#define GENERIC_AMBIENCE22             182
#define SECRETLEVELSND                 183
#define GENERIC_AMBIENCE8              184
#define GENERIC_AMBIENCE9              185
#define GENERIC_AMBIENCE10             186
#define GENERIC_AMBIENCE11             187
#define GENERIC_AMBIENCE12             188
#define GENERIC_AMBIENCE13             189
#define GENERIC_AMBIENCE14             190
#define GENERIC_AMBIENCE15             192
#define GENERIC_AMBIENCE16             193
#define FIRE_CRACKLE                   194
#define BONUS_SPEECH1                  195
#define BONUS_SPEECH2                  196
#define BONUS_SPEECH3                  197
#define PIG_CAPTURE_DUKE               198
#define BONUS_SPEECH4                  199
#define DUKE_LAND_HURT                 200
#define DUKE_HIT_STRIPPER1             201
#define DUKE_TIP1                      202
#define DUKE_KILLED2                   203
#define PRED_ROAM2                     204
#define PIG_ROAM2                      205
#define DUKE_GETWEAPON1                206
#define DUKE_SEARCH2                   207
#define DUKE_CRACK2                    208
#define DUKE_SEARCH                    209
#define DUKE_GET                       210
#define DUKE_LONGTERM_PAIN             211
#define MONITOR_ACTIVE                 212
#define NITEVISION_ONOFF               213
#define DUKE_HIT_STRIPPER2             214
#define DUKE_CRACK_FIRST               215
#define DUKE_USEMEDKIT                 216
#define DUKE_TAKEPILLS                 217
#define DUKE_PISSRELIEF                218
#define SELECT_WEAPON                  219
#define WATER_GURGLE                   220
#define DUKE_GETWEAPON4                221
#define JIBBED_ACTOR1                  222
#define JIBBED_ACTOR2                  223
#define JIBBED_ACTOR3                  224
#define JIBBED_ACTOR4                  225
#define JIBBED_ACTOR5                  226
#define JIBBED_ACTOR6                  227
#define JIBBED_ACTOR7                  228
#define DUKE_GOTHEALTHATLOW            229
#define BOSSTALKTODUKE                 230
#define WAR_AMBIENCE1                  231
#define WAR_AMBIENCE2                  232
#define WAR_AMBIENCE3                  233
#define WAR_AMBIENCE4                  234
#define WAR_AMBIENCE5                  235
#define WAR_AMBIENCE6                  236
#define WAR_AMBIENCE7                  237
#define WAR_AMBIENCE8                  238
#define WAR_AMBIENCE9                  239
#define WAR_AMBIENCE10                 240
#define ALIEN_TALK1                    241
#define ALIEN_TALK2                    242
#define EXITMENUSOUND                  243
#define FLY_BY                         244
#define DUKE_SCREAM                    245
#define SHRINKER_HIT                   246
#define RATTY                          247
#define INTO_MENU                      248
#define BONUSMUSIC                     249
#define DUKE_BOOBY                     250
#define DUKE_TALKTOBOSSFALL            251
#define DUKE_LOOKINTOMIRROR            252
#define PIG_ROAM3                      253
#define KILLME                         254
#define DRON_JETSND                    255
#define SPACE_DOOR1                    256
#define SPACE_DOOR2                    257
#define SPACE_DOOR3                    258
#define SPACE_DOOR4                    259
#define SPACE_DOOR5                    260
#define ALIEN_ELEVATOR1                261
#define VAULT_DOOR                     262
#define JIBBED_ACTOR13                 263
#define DUKE_GETWEAPON6                264
#define JIBBED_ACTOR8                  265
#define JIBBED_ACTOR9                  266
#define JIBBED_ACTOR10                 267
#define JIBBED_ACTOR11                 268
#define JIBBED_ACTOR12                 269
#define DUKE_KILLED4                   270
#define DUKE_KILLED5                   271
#define ALIEN_SWITCH1                  272
#define DUKE_STEPONFECES               273
#define DUKE_LONGTERM_PAIN2            274
#define DUKE_LONGTERM_PAIN3            275
#define DUKE_LONGTERM_PAIN4            276
#define COMPANB2                       277
#define KTIT                           278
#define HELICOP_IDLE                   279
#define STEPNIT                        280
#define SPACE_AMBIENCE1                281
#define SPACE_AMBIENCE2                282
#define SLIM_HATCH                     283
#define RIPHEADNECK                    284
#define FOUNDJONES                     285
#define ALIEN_DOOR1                    286
#define ALIEN_DOOR2                    287
#define ENDSEQVOL3SND4                 288
#define ENDSEQVOL3SND5                 289
#define ENDSEQVOL3SND6                 290
#define ENDSEQVOL3SND7                 291
#define ENDSEQVOL3SND8                 292
#define ENDSEQVOL3SND9                 293
#define WHIPYOURASS                    294
#define ENDSEQVOL2SND1                 295
#define ENDSEQVOL2SND2                 296
#define ENDSEQVOL2SND3                 297
#define ENDSEQVOL2SND4                 298
#define ENDSEQVOL2SND5                 299
#define ENDSEQVOL2SND6                 300
#define ENDSEQVOL2SND7                 301
#define GENERIC_AMBIENCE23             302
#define SOMETHINGFROZE                 303
#define DUKE_LONGTERM_PAIN5            304
#define DUKE_LONGTERM_PAIN6            305
#define DUKE_LONGTERM_PAIN7            306
#define DUKE_LONGTERM_PAIN8            307
#define WIND_REPEAT                    308
#define MYENEMY_ROAM                   309
#define MYENEMY_HURT                   310
#define MYENEMY_DEAD                   311
#define MYENEMY_SHOOT                  312
#define STORE_MUSIC                    313
#define STORE_MUSIC_BROKE              314
#define ACTOR_GROWING                  315
#define NEWBEAST_ROAM                  316
#define NEWBEAST_RECOG                 317
#define NEWBEAST_ATTACK                318
#define NEWBEAST_PAIN                  319
#define NEWBEAST_DYING                 320
#define NEWBEAST_SPIT                  321
#define VOL4_1                         322
#define SUPERMARKET                    323
#define MOUSEANNOY                     324
#define BOOKEM                         325
#define SUPERMARKETCRY                 326
#define DESTRUCT                       327
#define EATFOOD                        328
#define MAKEMYDAY                      329
#define WITNESSSTAND                   330
#define VACATIONSPEECH                 331
#define YIPPEE1                        332
#define YOHOO1                         333
#define YOHOO2                         334
#define DOLPHINSND                     335
#define TOUGHGALSND1                   336
#define TOUGHGALSND2                   337
#define TOUGHGALSND3                   338
#define TOUGHGALSND4                   339
#define TANK_ROAM                      340
#define BOS4_ROAM                      341
#define BOS4_RECOG                     342
#define BOS4_ATTACK                    343
#define BOS4_PAIN                      344
#define BOS4_DYING                     345
#define NEWBEAST_ATTACKMISS            346
#define VOL4_2                         347
#define COOKINGDEEPFRIER               348
#define WHINING_DOG                    349
#define DEAD_DOG                       350
#define LIGHTNING_SLAP                 351
#define THUNDER                        352
#define HAPPYMOUSESND1                 353
#define HAPPYMOUSESND2                 354
#define HAPPYMOUSESND3                 355
#define HAPPYMOUSESND4                 356
#define ALARM                          357
#define RAIN                           358
#define DTAG_GREENRUN                  359
#define DTAG_BROWNRUN                  360
#define DTAG_GREENSCORE                361
#define DTAG_BROWNSCORE                362
#define INTRO4_1                       363
#define INTRO4_2                       364
#define INTRO4_3                       365
#define INTRO4_4                       366
#define INTRO4_5                       367
#define INTRO4_6                       368
#define SCREECH                        369
#define BOSS4_DEADSPEECH               370
#define BOSS4_FIRSTSEE                 371
#define PARTY_SPEECH                   372
#define POSTAL_SPEECH                  373
#define TGSPEECH                       374
#define DOGROOMSPEECH                  375
#define SMACKED                        376
#define MDEVSPEECH                     377
#define AREA51SPEECH                   378
#define JEEPSOUND                      379
#define BIGDOORSLAM                    380
#define BOS4_LAY                       381
#define WAVESOUND                      382
#define ILLBEBACK                      383
#define VOL4ENDSND1                    384
#define VOL4ENDSND2                    385
#define EXPANDERHIT                    386
#define SNAKESPEECH                    387
#define EXPANDERSHOOT                  388
#define GETBACKTOWORK                  389
#define JIBBED_ACTOR14                 390
#define JIBBED_ACTOR15                 391
#define INTRO4_B                       392
#define BIGBANG                        393
#define HORNSND                        394
#define BELLSND                        395
#define GOAWAY                         396
#define JOKE                           397


code:
//-------------------------------------------------------------------------
/*
Copyright (C) 2016 EDuke32 developers and contributors

This file is part of EDuke32.

EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
//-------------------------------------------------------------------------

#include "compat.h"

#include "duke3d.h"
#include "renderlayer.h" // for win_gethwnd()
#include "al_midi.h"
#include <atomic>

#define DQSIZE 128

int32_t g_numEnvSoundsPlaying, g_highestSoundIdx = 0;

static int32_t MusicIsWaveform = 0;
static char *MusicPtr = NULL;
static int32_t MusicVoice = -1;
static bool MusicPaused = false;
static bool SoundPaused = false;

std::atomic<uint32_t> dnum;
uint32_t dq[DQSIZE];

void S_SoundStartup(void)
{
#ifdef MIXERTYPEWIN
    void *initdata = (void *) win_gethwnd(); // used for DirectSound
#else
    void *initdata = NULL;
#endif

    initprintf("Initializing sound... ");

    if (FX_Init(ud.config.NumVoices, ud.config.NumChannels, ud.config.MixRate, initdata) != FX_Ok)
    {
        initprintf("failed! %s\n", FX_ErrorString(FX_Error));
        return;
    }

    initprintf("%d voices, %d channels, %d-bit %d Hz\n", ud.config.NumVoices, ud.config.NumChannels,
        ud.config.NumBits, ud.config.MixRate);

    for (int i = 0; i <= g_highestSoundIdx; ++i)
    {
        for (auto & voice : g_sounds[i].voices)
        {
            g_sounds[i].num = 0;
            voice.id        = 0;
            voice.owner     = -1;
            voice.dist      = UINT16_MAX;
            voice.clock     = 0;
        }

        g_soundlocks[i] = 199;
    }

    if (REALITY)
        RT_InitSound();

    S_PrecacheSounds();

    FX_SetVolume(ud.config.FXVolume);
    S_MusicVolume(ud.config.MusicVolume);

    FX_SetCallBack(S_Callback);
}

void S_SoundShutdown(void)
{
    if (MusicVoice >= 0)
        S_MusicShutdown();

    if (FX_Shutdown() != FX_Ok)
    {
        Bsprintf(tempbuf, "S_SoundShutdown(): error: %s", FX_ErrorString(FX_Error));
        G_GameExit(tempbuf);
    }
}

void S_MusicStartup(void)
{
    initprintf("Initializing MIDI driver... ");

    int status;
    if ((status = MUSIC_Init(ud.config.MusicDevice)) == MUSIC_Ok)
    {
        if (ud.config.MusicDevice == ASS_AutoDetect)
            ud.config.MusicDevice = MIDI_GetDevice();
    }
    else if ((status = MUSIC_Init(ASS_AutoDetect)) == MUSIC_Ok)
    {
        ud.config.MusicDevice = MIDI_GetDevice();
    }
    else
    {
        initprintf("S_MusicStartup(): failed initializing: %s\n", MUSIC_ErrorString(status));
        return;
    }

    MUSIC_SetVolume(ud.config.MusicVolume);

    auto const fil = kopen4load("d3dtimbr.tmb", 0);

    if (fil != buildvfs_kfd_invalid)
    {
        int l = kfilelength(fil);
        auto tmb = (uint8_t *)Xmalloc(l);
        kread(fil, tmb, l);
        AL_RegisterTimbreBank(tmb);
        Xfree(tmb);
        kclose(fil);
    }
}

void S_MusicShutdown(void)
{
    S_StopMusic();

    if (MUSIC_Shutdown() != MUSIC_Ok)
        initprintf("%s\n", MUSIC_ErrorString(MUSIC_ErrorCode));
}

void S_PauseMusic(bool paused)
{
    if (MusicPaused == paused || (MusicIsWaveform && MusicVoice < 0))
        return;

    MusicPaused = paused;

    if (REALITY && g_musicIndex == MUS_INTRO)
    {
        RT_PauseSong(paused);
        return;
    }

    if (MusicIsWaveform)
    {
        FX_PauseVoice(MusicVoice, paused);
        return;
    }

    if (paused)
        MUSIC_Pause();
    else
        MUSIC_Continue();
}

void S_PauseSounds(bool paused)
{
    if (SoundPaused == paused)
        return;

    SoundPaused = paused;

    for (int i = 0; i <= g_highestSoundIdx; ++i)
    {
        for (auto & voice : g_sounds[i].voices)
            if (voice.id > 0)
                FX_PauseVoice(voice.id, paused);
    }
}

void S_MusicVolume(int32_t volume)
{
    if (MusicIsWaveform && MusicVoice >= 0)
        FX_SetPan(MusicVoice, volume, volume, volume);

    MUSIC_SetVolume(volume);
}

void S_RestartMusic(void)
{
    if (ud.recstat != 2 && g_player[myconnectindex].ps->gm&MODE_GAME)
    {
        S_PlayLevelMusicOrNothing(g_musicIndex);
    }
    else
    {
        S_PlaySpecialMusicOrNothing(MUS_INTRO);
    }
}

void S_MenuSound(void)
{
    static int SoundNum;
    int const menusnds[] = {
        LASERTRIP_EXPLODE, DUKE_GRUNT,       DUKE_LAND_HURT,   CHAINGUN_FIRE, SQUISHED,      KICK_HIT,
        PISTOL_RICOCHET,   PISTOL_BODYHIT,   PISTOL_FIRE,      SHOTGUN_FIRE,  BOS1_WALK,     RPG_EXPLODE,
        PIPEBOMB_BOUNCE,   PIPEBOMB_EXPLODE, NITEVISION_ONOFF, RPG_SHOOT,     SELECT_WEAPON,
    };
    int s = RR ? 390 : (REALITY ? 0xaa : menusnds[SoundNum++ % ARRAY_SIZE(menusnds)]);
    if (s != -1)
        S_PlaySound(s);
}

static int S_PlayMusic(const char *fn, int loop)
{
    if (!ud.config.MusicToggle)
        return 0;

    if (fn == NULL)
        return 1;

    int32_t fp = S_OpenAudio(fn, 0, 1);
    if (EDUKE32_PREDICT_FALSE(fp < 0))
    {
        OSD_Printf(OSD_ERROR "S_PlayMusic(): error: can't open \"%s\" for playback!\n",fn);
        return 2;
    }

    int32_t MusicLen = kfilelength(fp);

    if (EDUKE32_PREDICT_FALSE(MusicLen < 4))
    {
        OSD_Printf(OSD_ERROR "S_PlayMusic(): error: empty music file \"%s\"\n", fn);
        kclose(fp);
        return 3;
    }

    char * MyMusicPtr = (char *)Xaligned_alloc(16, MusicLen);
    int MyMusicSize = kread(fp, MyMusicPtr, MusicLen);

    if (EDUKE32_PREDICT_FALSE(MyMusicSize != MusicLen))
    {
        OSD_Printf(OSD_ERROR "S_PlayMusic(): error: read %d bytes from \"%s\", expected %d\n",
                   MyMusicSize, fn, MusicLen);
        kclose(fp);
        ALIGNED_FREE_AND_NULL(MyMusicPtr);
        return 4;
    }

    kclose(fp);

    if (!Bmemcmp(MyMusicPtr, "MThd", 4))
    {
        if (REALITY && g_musicIndex == MUS_INTRO)
            RT_StopSong();

        int32_t retval = MUSIC_PlaySong(MyMusicPtr, MyMusicSize, loop);

        if (retval != MUSIC_Ok)
        {
            ALIGNED_FREE_AND_NULL(MyMusicPtr);
            return 5;
        }

        if (MusicIsWaveform && MusicVoice >= 0)
        {
            FX_StopSound(MusicVoice);
            MusicVoice = -1;
        }

        MusicIsWaveform = 0;
        ALIGNED_FREE_AND_NULL(MusicPtr);
        MusicPtr    = MyMusicPtr;
        g_musicSize = MyMusicSize;
    }
    else
    {
        if (REALITY && g_musicIndex == MUS_INTRO)
            RT_StopSong();

        int MyMusicVoice = FX_Play(MyMusicPtr, MusicLen, loop ? 0 : -1, 0, 0, ud.config.MusicVolume, ud.config.MusicVolume, ud.config.MusicVolume,
                                   FX_MUSIC_PRIORITY, fix16_one, MUSIC_ID);

        if (MyMusicVoice <= FX_Ok)
        {
            ALIGNED_FREE_AND_NULL(MyMusicPtr);
            return 5;
        }

        if (MusicIsWaveform && MusicVoice >= 0)
            FX_StopSound(MusicVoice);

        MUSIC_StopSong();

        MusicVoice      = MyMusicVoice;
        MusicIsWaveform = 1;
        ALIGNED_FREE_AND_NULL(MusicPtr);
        MusicPtr    = MyMusicPtr;
        g_musicSize = MyMusicSize;
    }

    return 0;
}

static void S_SetMusicIndex(unsigned int m)
{
    g_musicIndex = m;
    ud.music_episode = m / MAXLEVELS;
    ud.music_level   = m % MAXLEVELS;
}

bool S_TryPlayLevelMusic(unsigned int m)
{
    if (RR)
        return 1;
    char const * musicfn = g_mapInfo[m].musicfn;

    if (musicfn != NULL)
    {
        if (!S_PlayMusic(musicfn, 1))
        {
            S_SetMusicIndex(m);
            return false;
        }
    }

    return true;
}

void S_PlayLevelMusicOrNothing(unsigned int m)
{
    if (S_TryPlayLevelMusic(m))
    {
        S_StopMusic();
        S_SetMusicIndex(m);
    }
}

int S_TryPlaySpecialMusic(unsigned int m)
{
    if (REALITY && m == MUS_INTRO)
    {
        if (g_musicIndex != MUS_INTRO)
            S_StopMusic();
        if (ud.config.MusicToggle)
            RT_PlaySong();
        S_SetMusicIndex(m);
        return 0;
    }
    if (RR)
        return 1;
    char const * musicfn = g_mapInfo[m].musicfn;
    if (musicfn != NULL)
    {
        if (!S_PlayMusic(musicfn, 1))
        {
            S_SetMusicIndex(m);
            return 0;
        }
    }

    return 1;
}

void S_PlayRRMusic(int newTrack)
{
    char fileName[16];
    if (!RR)
        return;
    S_StopMusic();
    g_cdTrack = newTrack != -1 ? newTrack : g_cdTrack+1;
    if (newTrack != 10 && (g_cdTrack > 9 || g_cdTrack < 2))
        g_cdTrack = 2;

    Bsprintf(fileName, "track%.2d.ogg", g_cdTrack);
    S_PlayMusic(fileName, 0);
}

void S_PlaySpecialMusicOrNothing(unsigned int m)
{
    if (S_TryPlaySpecialMusic(m))
    {
        S_StopMusic();
        S_SetMusicIndex(m);
    }
}

int32_t S_GetMusicPosition(void)
{
    int32_t position = 0;

    if (MusicIsWaveform)
        FX_GetPosition(MusicVoice, &position);

    return position;
}

void S_SetMusicPosition(int32_t position)
{
    if (MusicIsWaveform)
        FX_SetPosition(MusicVoice, position);
}

void S_StopMusic(void)
{
    MusicPaused = 0;

    if (REALITY && g_musicIndex == MUS_INTRO)
    {
        RT_StopSong();
        return;
    }

    if (MusicIsWaveform && MusicVoice >= 0)
    {
        FX_StopSound(MusicVoice);
        MusicVoice = -1;
        MusicIsWaveform = 0;
    }

    MUSIC_StopSong();

    ALIGNED_FREE_AND_NULL(MusicPtr);
    g_musicSize = 0;
}

void S_Cleanup(void)
{
    static uint32_t ldnum;
    uint32_t const odnum = dnum;

    while (ldnum < odnum)
    {
        uint32_t num = dq[ldnum++ & (DQSIZE - 1)];

        // negative index is RTS playback
        if ((int32_t)num < 0)
        {
            if (rts_lumplockbyte[-(int32_t)num] >= 200)
                rts_lumplockbyte[-(int32_t)num]--;
            continue;
        }

        // num + (MAXSOUNDS*MAXSOUNDINSTANCES) is a sound played globally
        // for which there was no open slot to keep track of the voice
        if (num >= (MAXSOUNDS*MAXSOUNDINSTANCES))
        {
            --g_soundlocks[num-(MAXSOUNDS*MAXSOUNDINSTANCES)];
            continue;
        }

        RT_FreeSoundSlotId(num);

        int const vidx = num & (MAXSOUNDINSTANCES - 1);

        num = (num - vidx) / MAXSOUNDINSTANCES;

        auto &snd   = g_sounds[num];
        auto &voice = g_sounds[num].voices[vidx];

        int const spriteNum = voice.owner;

        if (EDUKE32_PREDICT_FALSE(snd.num > MAXSOUNDINSTANCES))
            OSD_Printf(OSD_ERROR "S_Cleanup(): num exceeds MAXSOUNDINSTANCES! g_sounds[%d].num %d wtf?\n", num, snd.num);

        if (snd.num > 0)
            --snd.num;

        // MUSICANDSFX uses t_data[0] to control restarting the sound
        // CLEAR_SOUND_T0
        if (spriteNum != -1 && S_IsAmbientSFX(spriteNum) && sector[SECT(spriteNum)].lotag < 3)  // ST_2_UNDERWATER
            actor[spriteNum].t_data[0] = 0;

        voice.owner = -1;
        voice.id    = 0;
        voice.dist  = UINT16_MAX;
        voice.clock = 0;

        --g_soundlocks[num];
    }
}

// returns number of bytes read
int32_t S_LoadSound(int num)
{
    if ((unsigned)num > (unsigned)g_highestSoundIdx)
        return 0;

    if (g_sounds[num].filename == NULL)
    {
        if (REALITY)
            return RT_LoadSound(num);
        return 0;
    }

    auto &snd = g_sounds[num];

    int32_t fp = S_OpenAudio(snd.filename, g_loadFromGroupOnly, 0);

    if (EDUKE32_PREDICT_FALSE(fp == -1))
    {
        OSD_Printf(OSDTEXT_RED "Sound %s(#%d) not found!\n", snd.filename, num);
        return 0;
    }

    int32_t l = kfilelength(fp);
    g_soundlocks[num] = 200;
    snd.siz = l;
    g_cache.allocateBlock((intptr_t *)&snd.ptr, l, (char *)&g_soundlocks[num]);
    l = kread(fp, snd.ptr, l);
    kclose(fp);

    return l;
}

void S_PrecacheSounds(void)
{
    for (int32_t i = 0, j = 0; i <= g_highestSoundIdx; ++i)
        if (g_sounds[i].ptr == 0)
        {
            j++;
            if ((j&7) == 0)
                G_HandleAsync();

            S_LoadSound(i);
        }
}

static inline int S_GetPitch(int num)
{
    auto const &snd   = g_sounds[num];
    int const   range = klabs(snd.pe - snd.ps);

    return (range == 0) ? snd.ps : min(snd.ps, snd.pe) + wrand() % range;
}

static int S_TakeSlot(int soundNum)
{
    S_Cleanup();

    uint16_t dist  = 0;
    uint16_t clock = 0;

    int bestslot = 0;
    int slot     = 0;

    auto &snd = g_sounds[soundNum];

    while (slot < MAXSOUNDINSTANCES && snd.voices[slot].id > 0)
    {
        auto &voice = snd.voices[slot];

        if (voice.dist > dist || (voice.dist == dist && voice.clock > clock))
        {
            clock = voice.clock;
            dist  = voice.dist;

            bestslot = slot;
        }

        slot++;
    }

    if (slot != MAXSOUNDINSTANCES)
        return slot;

    if (FX_SoundActive(snd.voices[bestslot].id))
        FX_StopSound(snd.voices[bestslot].id);

    dq[dnum++ & (DQSIZE-1)] = (soundNum * MAXSOUNDINSTANCES) + bestslot;
    S_Cleanup();

    return bestslot;
}

static int S_GetSlot(int soundNum)
{
    int slot = 0;

    while (slot < MAXSOUNDINSTANCES && g_sounds[soundNum].voices[slot].id > 0)
        slot++;

    return slot == MAXSOUNDINSTANCES ? S_TakeSlot(soundNum) : slot;
}

static inline int S_GetAngle(int ang, const vec3_t *cam, const vec3_t *pos)
{
    return (2048 + ang - getangle(cam->x - pos->x, cam->y - pos->y)) & 2047;
}

static bool S_CalcDistAndAng(int32_t spriteNum, int32_t soundNum, int32_t sectNum, int32_t angle,
                                const vec3_t *cam, const vec3_t *pos,
                                int32_t *distPtr, int32_t *angPtr)
{
    int32_t sndang = 0, sndist = 0;
    bool explosion = false;

    if (PN(spriteNum) == APLAYER && P_Get(spriteNum) == screenpeek)
        goto sound_further_processing;

    sndang = S_GetAngle(angle, cam, pos);
    sndist = FindDistance3D(cam->x-pos->x, cam->y-pos->y, (cam->z-pos->z));

#ifdef SPLITSCREEN_MOD_HACKS
    if (g_fakeMultiMode==2)
    {
        // HACK for splitscreen mod: take the min of sound distances
        // to 1st and 2nd player.

        if (PN(spriteNum) == APLAYER && P_Get(spriteNum) == 1)
        {
            sndist = sndang = 0;
            goto sound_further_processing;
        }

        {
            const vec3_t *cam2 = &g_player[1].ps->pos;
            int32_t sndist2 = FindDistance3D(cam2->x-pos->x, cam2->y-pos->y, (cam2->z-pos->z));

            if (sndist2 < sndist)
            {
                cam = cam2;
                sectNum = g_player[1].ps->cursectnum;
                angle = g_player[1].ps->ang;

                sndist = sndist2;
                sndang = S_GetAngle(angle, cam, pos);
            }
        }
    }
#endif

    if ((g_sounds[soundNum].m & SF_GLOBAL) == 0 && S_IsAmbientSFX(spriteNum) && (sector[SECT(spriteNum)].lotag&0xff) < 9)  // ST_9_SLIDING_ST_DOOR
        sndist = divscale14(sndist, SHT(spriteNum)+1);

sound_further_processing:
    sndist += g_sounds[soundNum].vo;
    if (sndist < 0)
        sndist = 0;

    if ((unsigned)sectNum >= (unsigned)numsectors || (unsigned)SECT(spriteNum) >= (unsigned)numsectors
        || (sndist && PN(spriteNum) != MUSICANDSFX
        && !cansee(cam->x, cam->y, cam->z - (24 << 8), sectNum, SX(spriteNum), SY(spriteNum), SZ(spriteNum) - (24 << 8), SECT(spriteNum))))
        sndist += sndist>>(RR?2:5);

    switch (DYNAMICSOUNDMAP(soundNum))
    {
        case PIPEBOMB_EXPLODE__STATIC:
        case LASERTRIP_EXPLODE__STATIC:
        case RPG_EXPLODE__STATIC:
            explosion = true;
            if (sndist > 6144)
                sndist = 6144;
            break;
    }

    if ((g_sounds[soundNum].m & SF_GLOBAL) || sndist < ((255-LOUDESTVOLUME) << 6))
        sndist = ((255-LOUDESTVOLUME) << 6);

    *distPtr = sndist;
    *angPtr  = sndang;

    return explosion;
}

int S_PlaySound3D(int num, int spriteNum, const vec3_t *pos)
{
    int32_t j;

    if (!ud.config.SoundToggle) // check that the user returned -1, but only if -1 wasn't playing already (in which case, warn)
        return -1;

    int const sndNum = num;
    sound_t & snd    = g_sounds[sndNum];

    if (EDUKE32_PREDICT_FALSE((unsigned) sndNum > (unsigned) g_highestSoundIdx || (!(snd.m & SF_REALITY_INTERNAL) && snd.filename == NULL) || snd.ptr == NULL))
    {
        OSD_Printf("WARNING: invalid sound #%d\n", num);
        return -1;
    }

    const DukePlayer_t *const pPlayer = g_player[myconnectindex].ps;

    if (((snd.m & SF_ADULT) && ud.lockout) || (unsigned)spriteNum >= MAXSPRITES || (pPlayer->gm & MODE_MENU) || !FX_VoiceAvailable(snd.pr)
        || (pPlayer->timebeforeexit > 0 && pPlayer->timebeforeexit <= GAMETICSPERSEC * 3))
        return -1;

    // Duke talk
    if (snd.m & SF_TALK)
    {
        if ((g_netServer || ud.multimode > 1) && PN(spriteNum) == APLAYER && P_Get(spriteNum) != screenpeek) // other player sound
        {
            if ((ud.config.VoiceToggle & 4) != 4)
                return -1;
        }
        else if ((ud.config.VoiceToggle & 1) != 1)
            return -1;

        // don't play if any Duke talk sounds are already playing
        for (j = 0; j <= g_highestSoundIdx; ++j)
            if ((g_sounds[j].m & SF_TALK) && g_sounds[j].num > 0)
                return -1;
    }
    else if (snd.m & SF_DTAG)  // Duke-Tag sound
    {
        int const voice = S_PlaySound(sndNum);

        if (voice <= FX_Ok)
            return -1;

        j = 0;
        while (j < MAXSOUNDINSTANCES && snd.voices[j].id != voice)
            j++;

#ifdef DEBUGGINGAIDS
        if (EDUKE32_PREDICT_FALSE(j >= MAXSOUNDINSTANCES))
        {
            OSD_Printf(OSD_ERROR "%s %d: WTF?\n", __FILE__, __LINE__);
            return -1;
        }
#endif

        snd.voices[j].owner = spriteNum;

        return voice;
    }

    int32_t    sndist, sndang;
    int const  explosionp = S_CalcDistAndAng(spriteNum, sndNum, CAMERA(sect), fix16_to_int(CAMERA(q16ang)), &CAMERA(pos), pos, &sndist, &sndang);
    int        pitch      = S_GetPitch(sndNum);
    auto const pOther     = g_player[screenpeek].ps;

#ifdef SPLITSCREEN_MOD_HACKS
    if (g_fakeMultiMode==2)
    {
        // splitscreen HACK
        if (g_player[1].ps->i == spriteNum)
            pOther = g_player[1].ps;
}
#endif

    if (pOther->sound_pitch)
        pitch += pOther->sound_pitch;

    if (explosionp)
    {
        if (pOther->cursectnum > -1 && sector[pOther->cursectnum].lotag == ST_2_UNDERWATER)
            pitch -= 1024;
    }
    else
    {
        if (!REALITY && sndist > 32767 && PN(spriteNum) != MUSICANDSFX && (snd.m & (SF_LOOP|SF_MSFX)) == 0)
            return -1;

        if (pOther->cursectnum > -1 && sector[pOther->cursectnum].lotag == ST_2_UNDERWATER
            && (snd.m & SF_TALK) == 0)
            pitch = -768;
    }

    if (snd.num > 0 && PN(spriteNum) != MUSICANDSFX)
        S_StopEnvSound(sndNum, spriteNum);

    if (++g_soundlocks[sndNum] < 200)
        g_soundlocks[sndNum] = 200;

    int const sndSlot = S_GetSlot(sndNum);

    if (sndSlot >= MAXSOUNDINSTANCES)
    {
        g_soundlocks[sndNum]--;
        return -1;
    }

    int const repeatp = (snd.m & SF_LOOP);

    if (repeatp && (snd.m & SF_ONEINST_INTERNAL) && snd.num > 0)
    {
        g_soundlocks[sndNum]--;
        return -1;
    }

    int voice = FX_Ok;
    if (REALITY && (snd.m & SF_REALITY_INTERNAL))
    {
        auto rtsnd = RT_FindSoundSlot(sndNum, (sndNum * MAXSOUNDINSTANCES) + sndSlot);
        if (rtsnd)
        {
            voice = FX_StartDemandFeedPlayback3D(RT_SoundDecodeEnv, 16, 1, rt_soundrate[sndNum] + pitch, 0, sndang >> 4, sndist >> 6,
                                                 snd.pr, snd.volume, (sndNum * MAXSOUNDINSTANCES) + sndSlot, rtsnd);
            if (voice <= FX_Ok)
                RT_FreeSoundSlot(rtsnd);
        }
    }
    else
    {
        voice = FX_Play3D(snd.ptr, snd.siz, repeatp ? FX_LOOP : FX_ONESHOT, pitch, sndang >> 4, sndist >> 6,
                          snd.pr, snd.volume, (sndNum * MAXSOUNDINSTANCES) + sndSlot);
    }

    if (voice <= FX_Ok)
    {
        g_soundlocks[sndNum]--;
        return -1;
    }

    snd.num++;
    snd.voices[sndSlot].owner = spriteNum;
    snd.voices[sndSlot].id    = voice;
    snd.voices[sndSlot].dist  = sndist >> 6;
    snd.voices[sndSlot].clock = 0;

    return voice;
}

int S_PlaySound(int num)
{
    int sndnum;

    if (!ud.config.SoundToggle) // check that the user returned -1, but only if -1 wasn't playing already (in which case, warn)
        return -1;

    sound_t & snd = g_sounds[num];

    if (EDUKE32_PREDICT_FALSE((unsigned)num > (unsigned)g_highestSoundIdx || (!(snd.m & SF_REALITY_INTERNAL) && snd.filename == NULL) || snd.ptr == NULL))
    {
        OSD_Printf("WARNING: invalid sound #%d\n",num);
        return -1;
    }

    if ((!(ud.config.VoiceToggle & 1) && (snd.m & SF_TALK)) || ((snd.m & SF_ADULT) && ud.lockout) || !FX_VoiceAvailable(snd.pr))
        return -1;

    int const pitch = S_GetPitch(num);

    if (++g_soundlocks[num] < 200)
        g_soundlocks[num] = 200;

    sndnum = S_GetSlot(num);

    if (sndnum >= MAXSOUNDINSTANCES)
    {
        g_soundlocks[num]--;
        return -1;
    }

    int voice = FX_Ok;

    if (REALITY && (snd.m & SF_REALITY_INTERNAL))
    {
        auto rtsnd = RT_FindSoundSlot(num, (num * MAXSOUNDINSTANCES) + sndnum);
        if (rtsnd)
        {
            voice = (snd.m & SF_LOOP) ? FX_StartDemandFeedPlayback(RT_SoundDecodeEnv, 16, 1, rt_soundrate[num] + pitch, 0, LOUDESTVOLUME, LOUDESTVOLUME,
                                                                   LOUDESTVOLUME, snd.pr, snd.volume, (num * MAXSOUNDINSTANCES) + sndnum, rtsnd)
                                      : FX_StartDemandFeedPlayback3D(RT_SoundDecodeEnv, 16, 1, rt_soundrate[num] + pitch, 0, 0, 255 - LOUDESTVOLUME, snd.pr, snd.volume,
                                                                     (num * MAXSOUNDINSTANCES) + sndnum, rtsnd);
            if (voice <= FX_Ok)
                RT_FreeSoundSlot(rtsnd);
        }
    }
    else
    {
        voice = (snd.m & SF_LOOP) ? FX_Play(snd.ptr, snd.siz, 0, -1, pitch, LOUDESTVOLUME, LOUDESTVOLUME,
                                            LOUDESTVOLUME, snd.pr, snd.volume, (num * MAXSOUNDINSTANCES) + sndnum)
                                  : FX_Play3D(snd.ptr, snd.siz, FX_ONESHOT, pitch, 0, 255 - LOUDESTVOLUME, snd.pr, snd.volume,
                                              (num * MAXSOUNDINSTANCES) + sndnum);
    }

    if (voice <= FX_Ok)
    {
        g_soundlocks[num]--;
        return -1;
    }

    snd.num++;
    snd.voices[sndnum].owner = -1;
    snd.voices[sndnum].id    = voice;
    snd.voices[sndnum].dist  = 255 - LOUDESTVOLUME;
    snd.voices[sndnum].clock = 0;

    return voice;
}

int A_PlaySound(int soundNum, int spriteNum)
{
    if (EDUKE32_PREDICT_FALSE((unsigned)soundNum > (unsigned)g_highestSoundIdx)) return -1;

    return (unsigned)spriteNum >= MAXSPRITES ? S_PlaySound(soundNum) :
        S_PlaySound3D(soundNum, spriteNum, (vec3_t *)&sprite[spriteNum]);
}

void S_StopEnvSound(int32_t num, int32_t i)
{
    if (EDUKE32_PREDICT_FALSE((unsigned)num > (unsigned)g_highestSoundIdx) || g_sounds[num].num <= 0)
        return;

    int32_t j;

    do
    {
        for (j=0; j<MAXSOUNDINSTANCES; ++j)
        {
            if ((i == -1 && g_sounds[num].voices[j].id > FX_Ok) || (i != -1 && g_sounds[num].voices[j].owner == i))
            {
#ifdef DEBUGGINGAIDS
                if (EDUKE32_PREDICT_FALSE(i >= 0 && g_sounds[num].voices[j].id <= FX_Ok))
                    initprintf(OSD_ERROR "S_StopEnvSound(): bad voice %d for sound ID %d index %d!\n", g_sounds[num].voices[j].id, num, j);
                else
#endif
                if (g_sounds[num].voices[j].id > FX_Ok)
                {
                    FX_StopSound(g_sounds[num].voices[j].id);
                    S_Cleanup();
                    break;
                }
            }
        }
    }
    while (j < MAXSOUNDINSTANCES);
}

// Do not remove this or make it inline.
void S_StopAllSounds(void)
{
    FX_StopAllSounds();
}

void S_ChangeSoundPitch(int soundNum, int spriteNum, int pitchoffset)
{
    if ((unsigned)soundNum > (unsigned)g_highestSoundIdx || g_sounds[soundNum].num <= 0)
        return;

    for (auto &voice : g_sounds[soundNum].voices)
    {
        if ((spriteNum == -1 && voice.id > FX_Ok) || (spriteNum != -1 && voice.owner == spriteNum))
        {
            if (EDUKE32_PREDICT_FALSE(spriteNum >= 0 && voice.id <= FX_Ok))
                initprintf(OSD_ERROR "S_ChangeSoundPitch(): bad voice %d for sound ID %d!\n", voice.id, soundNum);
            else if (voice.id > FX_Ok && FX_SoundActive(voice.id))
            {
                if (g_sounds[spriteNum].m & SF_REALITY_INTERNAL)
                    FX_SetFrequency(voice.id, rt_soundrate[soundNum] + pitchoffset);
                else
                    FX_SetPitch(voice.id, pitchoffset);
            }
            break;
        }
    }
}

void S_Update(void)
{
    S_Cleanup();

    if ((g_player[myconnectindex].ps->gm & (MODE_GAME|MODE_DEMO)) == 0)
        return;

    if (RR && MusicIsWaveform && MusicVoice >= 0 && !FX_SoundActive(MusicVoice))
        S_PlayRRMusic();

    g_numEnvSoundsPlaying = 0;

    const vec3_t *c;
    int32_t ca,cs;

    if (ud.camerasprite == -1)
    {
        c = &CAMERA(pos);
        cs = CAMERA(sect);
        ca = fix16_to_int(CAMERA(q16ang));
    }
    else
    {
        c = (vec3_t *)&sprite[ud.camerasprite];
        cs = sprite[ud.camerasprite].sectnum;
        ca = sprite[ud.camerasprite].ang;
    }

    int       sndnum  = 0;
    int const highest = g_highestSoundIdx;

    do
    {
        if (g_sounds[sndnum].num == 0)
            continue;

        for (auto &voice : g_sounds[sndnum].voices)
        {
            int const spriteNum = voice.owner;

            if ((unsigned)spriteNum >= MAXSPRITES || voice.id <= FX_Ok || !FX_SoundActive(voice.id))
                continue;

            int32_t sndist, sndang;

            S_CalcDistAndAng(spriteNum, sndnum, cs, ca, c, (const vec3_t *)&sprite[spriteNum], &sndist, &sndang);

            if (S_IsAmbientSFX(spriteNum))
                g_numEnvSoundsPlaying++;

            // AMBIENT_SOUND
            FX_Pan3D(voice.id, sndang >> 4, sndist >> 6);
            voice.dist = sndist >> 6;
            voice.clock++;
        }
    } while (++sndnum <= highest);
}

void S_Callback(intptr_t num)
{
    if ((int32_t)num == MUSIC_ID)
        return;

    dq[dnum & (DQSIZE - 1)] = (uint32_t)num;
    dnum++;
}

void S_ClearSoundLocks(void)
{
#ifdef CACHING_DOESNT_SUCK
    int32_t i;
    int32_t const msp = g_highestSoundIdx;

    for (native_t i = 0; i < 11; ++i)
        if (rts_lumplockbyte[i] >= 200)
            rts_lumplockbyte[i] = 199;

    int32_t const msp = g_highestSoundIdx;

    for (native_t i = 0; i <= msp; ++i)
        if (g_soundlocks[i] >= 200)
            g_soundlocks[i] = 199;
#endif
}

bool A_CheckSoundPlaying(int spriteNum, int soundNum)
{
    if (EDUKE32_PREDICT_FALSE((unsigned)soundNum > (unsigned)g_highestSoundIdx)) return 0;

    if (g_sounds[soundNum].num > 0 && spriteNum >= 0)
    {
        for (auto &voice : g_sounds[soundNum].voices)
            if (voice.owner == spriteNum)
                return 1;
    }

    return (spriteNum == -1) ? (g_sounds[soundNum].num != 0) : 0;
}

// Check if actor <i> is playing any sound.
bool A_CheckAnySoundPlaying(int spriteNum)
{
    int const msp = g_highestSoundIdx;

    for (int j = 0; j <= msp; ++j)
    {
        for (auto &voice : g_sounds[j].voices)
            if (voice.owner == spriteNum)
                return 1;
    }

    return 0;
}

bool S_CheckSoundPlaying(int spriteNum, int soundNum)
{
    if (EDUKE32_PREDICT_FALSE((unsigned)soundNum > (unsigned)g_highestSoundIdx)) return 0;
    return (spriteNum == -1) ? (g_soundlocks[soundNum] > 200) : (g_sounds[soundNum].num != 0);
}


code:
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors

This file is part of EDuke32.

EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
//-------------------------------------------------------------------------

//****************************************************************************
//
// sounds.h
//
//****************************************************************************

#ifndef sounds_public_h_
#define sounds_public_h_

#include "sounds_common.h"

#ifdef __cplusplus
extern "C" {
#endif

// KEEPINSYNC lunatic/con_lang.lua
#define MAXSOUNDS           4096
#define MAXSOUNDINSTANCES   8
#define LOUDESTVOLUME       111
#define MUSIC_ID            -65536

typedef struct
{
    int16_t  owner;
    int16_t  id;
    uint16_t dist;
    uint16_t clock;
} assvoice_t;

typedef struct
{
    char *    ptr, *filename;                // 8b/16b
    int32_t   length, num, siz;              // 12b
    fix16_t   volume;                        // 4b
    assvoice_t voices[MAXSOUNDINSTANCES];  // 64b
    int16_t   ps, pe, vo;                    // 6b
    char      pr, m;                         // 2b
} sound_t;

extern char g_soundlocks[MAXSOUNDS];
extern sound_t g_sounds[MAXSOUNDS];
extern int32_t g_skillSoundVoice;
extern int32_t g_numEnvSoundsPlaying,g_highestSoundIdx;

bool A_CheckSoundPlaying(int spriteNum,int soundNum);
int A_PlaySound(int soundNum, int spriteNum);
void S_Callback(intptr_t num);
bool A_CheckAnySoundPlaying(int spriteNum);
bool S_CheckSoundPlaying(int spriteNum,int soundNum);
void S_Cleanup(void);
void S_ClearSoundLocks(void);
int32_t S_LoadSound(uint32_t num);
void S_PrecacheSounds(void);
void S_MenuSound(void);
void S_MusicShutdown(void);
void S_MusicStartup(void);
void S_MusicVolume(int32_t volume);
void S_RestartMusic(void);
void S_PauseMusic(bool paused);
void S_PauseSounds(bool paused);
void S_PlayRRMusic(int newTrack = -1);
bool S_TryPlayLevelMusic(unsigned int m);
void S_PlayLevelMusicOrNothing(unsigned int);
int S_TryPlaySpecialMusic(unsigned int);
void S_PlaySpecialMusicOrNothing(unsigned int);
int S_PlaySound(int num);
int S_PlaySound3D(int num, int spriteNum, const vec3_t *pos);
void S_SoundShutdown(void);
void S_SoundStartup(void);
void S_StopEnvSound(int32_t num,int32_t i);
void S_StopAllSounds(void);
void S_StopMusic(void);
void S_Update(void);
void S_ChangeSoundPitch(int soundNum, int spriteNum, int pitchoffset);
int32_t S_GetMusicPosition(void);
void S_SetMusicPosition(int32_t position);

static inline bool S_IsAmbientSFX(int spriteNum)
{
    return (sprite[spriteNum].picnum == MUSICANDSFX && sprite[spriteNum].lotag < 999);
}

#ifdef __cplusplus
}
#endif

#endif


code:
//-------------------------------------------------------------------------
/*
Copyright (C) 2013 EDuke32 developers and contributors

This file is part of EDuke32.

EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
//-------------------------------------------------------------------------

#ifndef EDUKE32_SOUNDS_COMMON_H
#define EDUKE32_SOUNDS_COMMON_H

// Sound flags
enum {
    SF_LOOP = 1,
    SF_MSFX = 2,
    SF_TALK = 4,
    SF_ADULT = 8,
    SF_GLOBAL = 16,
    SF_ONEINST_INTERNAL = 32,
    SF_REALITY_INTERNAL = 64,

    SF_DTAG = 128,
};

#endif


code:
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors

This file is part of EDuke32.

EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
//-------------------------------------------------------------------------

// Stripped sounds.c for use in Mapster32, breaks all ties to game & music

#include "compat.h"
#include "baselayer.h"

#include "fx_man.h"
#include "osd.h"

#include "cache1d.h"
#include "build.h"  // vec3_t
#include "editor.h"

#include "macros.h"
#include "common.h"

#ifdef _WIN32
#include "winlayer.h"
#endif

#include "sounds_mapster32.h"
#include "common.h"
#include "common_game.h"

#define LOUDESTVOLUME 150
#define MUSICANDSFX 5

static char SM32_havesound = 0;

static char SoundToggle = 1;
int32_t NumVoices = 32;
int32_t MixRate = 44100;

int32_t g_numEnvSoundsPlaying;

void MUSIC_Update(void) {}  // needed when linking

void S_Callback(uint32_t);

/*
===================
=
= SoundStartup
=
===================
*/

int32_t S_SoundStartup(void)
{
    int32_t status;
    void *initdata = 0;

    // TODO: read config
    int32_t FXVolume=220, /*NumVoices=32,*/ NumChannels=2;

#ifdef MIXERTYPEWIN
    initdata = (void *) win_gethwnd(); // used for DirectSound
#endif

    status = FX_Init(NumVoices, NumChannels, MixRate, initdata);
    if (status == FX_Ok)
    {
        FX_SetVolume(FXVolume);
#ifdef ASS_REVERSESTEREO
        FX_SetReverseStereo(0);
#endif
        FX_SetCallBack(S_Callback);
    }
    else
    {
        initprintf("Sound startup error: %s\n", FX_ErrorString(FX_Error));
        return -2;
    }

    SM32_havesound = 1;

    return 0;
}

/*
===================
=
= SoundShutdown
=
===================
*/

void S_SoundShutdown(void)
{
    int32_t status;

    if (!SM32_havesound)
        return;

    status = FX_Shutdown();
    if (status != FX_Ok)
        initprintf("Sound shutdown error: %s\n", FX_ErrorString(FX_Error));
}

int32_t S_LoadSound(uint32_t num)
{
    if (!SM32_havesound) return 0;
    if (num >= MAXSOUNDS || SoundToggle == 0) return 0;

    if (g_sounds[num].filename == NULL)
    {
        OSD_Printf(OSD_ERROR "Sound (#%d) not defined!\n",num);
        return 0;
    }

    int32_t fp = S_OpenAudio(g_sounds[num].filename, 0, 0);
    if (fp == -1)
    {
        OSD_Printf(OSDTEXT_RED "Sound %s(#%d) not found!\n",g_sounds[num].filename,num);
        return 0;
    }

    int32_t l = kfilelength(fp);
    g_sounds[num].soundsiz = l;

    g_sounds[num].lock = 200;

    cacheAllocateBlock((intptr_t *)&g_sounds[num].ptr,l,(char *)&g_sounds[num].lock);
    kread(fp, g_sounds[num].ptr , l);
    kclose(fp);
    return 1;
}

int32_t S_PlaySound3D(int32_t num, int32_t i, const vec3_t *pos)
{
    int32_t sndist, cx, cy, cz, j/*,k*/;
    int32_t pitche,pitchs,cs;
    int32_t voice, sndang, ca, pitch;

    //    if(num != 358) return 0;

    if (num >= MAXSOUNDS ||
            !SM32_havesound ||
//        ((g_sounds[num].m & SF_ADULT) && ud.lockout) ||
            SoundToggle == 0 ||
            g_sounds[num].num > 3 ||
            FX_VoiceAvailable(g_sounds[num].pr) == 0)
        return -1;

    if (g_sounds[num].m & SF_DTAG)
    {
        S_PlaySound(num);
        return 0;
    }

    if (g_sounds[num].m & SF_TALK)
    {
        for (j=0; j<MAXSOUNDS; j++)
//            for (k=0; k<g_sounds[j].num; k++)
            if ((g_sounds[j].num > 0) && (g_sounds[j].m & SF_TALK))
                return -1;
    }

    cx = pos->x;
    cy = pos->y;
    cz = pos->z;
    cs = cursectnum;
    ca = ang;

    sndist = FindDistance3D((cx-pos->x),(cy-pos->y),(cz-pos->z));

    if (i >= 0 && (g_sounds[num].m & SF_GLOBAL) == 0 && PN(i) == MUSICANDSFX && SLT(i) < 999 && (sector[SECT(i)].lotag&0xff) < 9)
        sndist = divscale14(sndist,(SHT(i)+1));

    pitchs = g_sounds[num].ps;
    pitche = g_sounds[num].pe;
    cx = klabs(pitche-pitchs);

    if (cx)
    {
        if (pitchs < pitche)
            pitch = pitchs + (wrand()%cx);
        else pitch = pitche + (wrand()%cx);
    }
    else pitch = pitchs;

    sndist += g_sounds[num].vo;
    if (sndist < 0) sndist = 0;
    if (cs > -1 && sndist && PN(i) != MUSICANDSFX && !cansee(cx,cy,cz-(24<<8),cs,SX(i),SY(i),SZ(i)-(24<<8),SECT(i)))
        sndist += sndist>>5;
    /*
        switch (num)
        {
        case PIPEBOMB_EXPLODE:
        case LASERTRIP_EXPLODE:
        case RPG_EXPLODE:
            if (sndist > (6144))
                sndist = 6144;
            if (g_player[screenpeek].ps->cursectnum > -1 && sector[g_player[screenpeek].ps->cursectnum].lotag == 2)
                pitch -= 1024;
            break;
        default:
    */
    if (cursectnum > -1 && sector[cursectnum].lotag == 2 && (g_sounds[num].m & SF_TALK) == 0)
        pitch = -768;
    if (sndist > 31444 && PN(i) != MUSICANDSFX)
        return -1;
//        break;
//    }

    if (g_sounds[num].num > 0 && PN(i) != MUSICANDSFX)
    {
        if (g_sounds[num].SoundOwner[0].ow == i) S_StopSound(num);
        else if (g_sounds[num].num > 1) S_StopSound(num);
//        else if (A_CheckEnemySprite(&sprite[i]) && sprite[i].extra <= 0) S_StopSound(num);
    }

    sndang = 2048 + ca - getangle(cx-pos->x,cy-pos->y);
    sndang &= 2047;

    if (g_sounds[num].ptr == 0)
    {
        if (S_LoadSound(num) == 0) return 0;
    }
    else
    {
        if (g_sounds[num].lock < 200)
            g_sounds[num].lock = 200;
        else g_sounds[num].lock++;
    }

    if (g_sounds[num].m & SF_GLOBAL) sndist = 0;

    if (sndist < ((255-LOUDESTVOLUME)<<6))
        sndist = ((255-LOUDESTVOLUME)<<6);

    if (g_sounds[num].m & SF_LOOP)
    {
        if (g_sounds[num].num > 0)
            return -1;

        voice = FX_Play(g_sounds[num].ptr, g_sounds[num].soundsiz, 0, -1,
                                  pitch, sndist>>6, sndist>>6, 0, g_sounds[num].pr, num);
    }
    else
    {
        voice = FX_Play3D(g_sounds[num].ptr, g_sounds[num].soundsiz, FX_ONESHOT,
                              pitch, sndang>>4, sndist>>6, g_sounds[num].pr, num);
    }

    if (voice >= FX_Ok)
    {
        g_sounds[num].SoundOwner[g_sounds[num].num].ow = i;
        g_sounds[num].SoundOwner[g_sounds[num].num].voice = voice;
        g_sounds[num].num++;
    }
    else g_sounds[num].lock--;
    return voice;
}

void S_PlaySound(int32_t num)
{
    int32_t pitch,pitche,pitchs,cx;
    int32_t voice;

    if (!SM32_havesound) return;
    if (SoundToggle==0) return;
    if ((unsigned)num >= MAXSOUNDS || !g_sounds[num].filename)
    {
        OSD_Printf("WARNING: invalid sound #%d\n",num);
        return;
    }
//    if ((g_sounds[num].m & SF_ADULT) && ud.lockout) return;
    if (FX_VoiceAvailable(g_sounds[num].pr) == 0) return;

    pitchs = g_sounds[num].ps;
    pitche = g_sounds[num].pe;
    cx = klabs(pitche-pitchs);

    if (cx)
    {
        if (pitchs < pitche)
            pitch = pitchs + (wrand()%cx);
        else pitch = pitche + (wrand()%cx);
    }
    else pitch = pitchs;

    if (g_sounds[num].ptr == 0)
    {
        if (S_LoadSound(num) == 0) return;
    }
    else
    {
        if (g_sounds[num].lock < 200)
            g_sounds[num].lock = 200;
        else g_sounds[num].lock++;
    }

    if (g_sounds[num].m & SF_LOOP)
    {
        voice = FX_Play(g_sounds[num].ptr, g_sounds[num].soundsiz, 0, -1,
                                  pitch,LOUDESTVOLUME,LOUDESTVOLUME,LOUDESTVOLUME,g_sounds[num].soundsiz, 1.f,num);
    }
    else
    {
        voice = FX_Play3D(g_sounds[num].ptr, g_sounds[num].soundsiz, FX_ONESHOT,
                              pitch,0,255-LOUDESTVOLUME,g_sounds[num].pr, 1.f, num);
    }

    if (voice >= FX_Ok)
    {
        g_sounds[num].SoundOwner[g_sounds[num].num].ow = -1;
        g_sounds[num].SoundOwner[g_sounds[num].num].voice = voice;
        g_sounds[num].num++;
        return;
    }
    g_sounds[num].lock--;
}

int32_t A_PlaySound(uint32_t num, int32_t i)
{
    if (num >= MAXSOUNDS) return -1;
    if (i < 0)
    {
        S_PlaySound(num);
        return 0;
    }

    return S_PlaySound3D(num,i, (vec3_t *)&sprite[i]);
}

void S_StopSound(int32_t num)
{
    if (num >= 0 && num < MAXSOUNDS)
        if (g_sounds[num].num > 0)
        {
            FX_StopSound(g_sounds[num].SoundOwner[g_sounds[num].num-1].voice);
            S_Callback(num);
        }
}

void S_StopEnvSound(int32_t num,int32_t i)
{
    int32_t j, k;

    if (num >= 0 && num < MAXSOUNDS)
        if (g_sounds[num].num > 0)
        {
            k = g_sounds[num].num;
            for (j=0; j<k; j++)
                if (g_sounds[num].SoundOwner[j].ow == i)
                {
                    FX_StopSound(g_sounds[num].SoundOwner[j].voice);
                    break;
                }
        }
}

// Do not remove this or make it inline.
void S_StopAllSounds(void)
{
    FX_StopAllSounds();
}

void S_Update(void)
{
    int32_t sndist, sx, sy, sz, cx, cy, cz;
    int32_t sndang,ca,j,k,i,cs;

    g_numEnvSoundsPlaying = 0;

    cx = pos.x;
    cy = pos.y;
    cz = pos.z;
    cs = cursectnum;
    ca = ang;

    for (j=0; j<MAXSOUNDS; j++)
        for (k=0; k<g_sounds[j].num; k++)
        {
            i = g_sounds[j].SoundOwner[k].ow;

            sx = sprite[i].x;
            sy = sprite[i].y;
            sz = sprite[i].z;

            sndang = 2048 + ca - getangle(cx-sx,cy-sy);
            sndang &= 2047;
            sndist = FindDistance3D((cx-sx),(cy-sy),(cz-sz));
            if (i >= 0 && (g_sounds[j].m & SF_GLOBAL) == 0 && PN(i) == MUSICANDSFX && SLT(i) < 999 && (sector[SECT(i)].lotag&0xff) < 9)
                sndist = divscale14(sndist,(SHT(i)+1));

            sndist += g_sounds[j].vo;
            if (sndist < 0) sndist = 0;

            if (cs > -1 && sndist && PN(i) != MUSICANDSFX && !cansee(cx,cy,cz-(24<<8),cs,sx,sy,sz-(24<<8),SECT(i)))
                sndist += sndist>>5;

            if (PN(i) == MUSICANDSFX && SLT(i) < 999)
                g_numEnvSoundsPlaying++;
            /*
                        switch (j)
                        {
                        case PIPEBOMB_EXPLODE:
                        case LASERTRIP_EXPLODE:
                        case RPG_EXPLODE:
                            if (sndist > (6144)) sndist = (6144);
                            break;
                        default:
            */
            if (sndist > 31444 && PN(i) != MUSICANDSFX)
            {
                S_StopSound(j);
                continue;
            }
//            }

            if (g_sounds[j].ptr == 0 && S_LoadSound(j) == 0) continue;
            if (g_sounds[j].m & SF_GLOBAL) sndist = 0;

            if (sndist < ((255-LOUDESTVOLUME)<<6))
                sndist = ((255-LOUDESTVOLUME)<<6);

            FX_Pan3D(g_sounds[j].SoundOwner[k].voice,sndang>>4,sndist>>6);
        }
}

void S_Callback(uint32_t num)
{
    int32_t i,j,k;

    k = g_sounds[num].num;

    if (k > 0)
    {
        if ((g_sounds[num].m & SF_GLOBAL) == 0)
            for (j=0; j<k; j++)
            {
                i = g_sounds[num].SoundOwner[j].ow;
                if (i < 0)
                    continue;

                if (sprite[i].picnum == MUSICANDSFX && sector[sprite[i].sectnum].lotag < 3 && sprite[i].lotag < 999)
                {
                    extern uint8_t g_ambiencePlaying[MAXSPRITES>>3];

                    g_ambiencePlaying[i>>3] &= ~(1<<(i&7));

                    if (j < k-1)
                    {
                        g_sounds[num].SoundOwner[j].voice = g_sounds[num].SoundOwner[k-1].voice;
                        g_sounds[num].SoundOwner[j].ow     = g_sounds[num].SoundOwner[k-1].ow;
                    }
                    break;
                }
            }

        g_sounds[num].num--;
        g_sounds[num].SoundOwner[k-1].ow = -1;
    }

    g_sounds[num].lock--;
}

void S_ClearSoundLocks(void)
{
    int32_t i;

    for (i=0; i<MAXSOUNDS; i++)
        if (g_sounds[i].lock >= 200)
            g_sounds[i].lock = 199;
}

int32_t A_CheckSoundPlaying(int32_t i, int32_t num)
{
    UNREFERENCED_PARAMETER(i);
    if (num < 0) num=0;	// FIXME
    return (g_sounds[num].num > 0);
}

int32_t S_CheckSoundPlaying(int32_t i, int32_t num)
{
    if (i == -1)
    {
        if (g_sounds[num].lock >= 200)
            return 1;
        return 0;
    }
    return g_sounds[num].num;
}

int32_t S_SoundsPlaying(int32_t i)
{
    int32_t j = MAXSOUNDS-1;
    for (; j>=0; j--)
        if (g_sounds[j].SoundOwner[0].ow == i)
            break;

    return j;
}

int32_t S_InvalidSound(int32_t num)
{
    return (unsigned) num >= MAXSOUNDS;
}

int32_t S_SoundFlags(int32_t num)
{
    return g_sounds[num].m;
}


code:
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors

This file is part of EDuke32.

EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
//-------------------------------------------------------------------------

#ifndef sounds_mapster32_h_
#define sounds_mapster32_h_

#include "build.h"
#include "sounds_common.h"

#pragma pack(push,1)

/// vvv sound structs from duke3d.h
typedef struct {
    int32_t voice;
    int32_t ow;
} SOUNDOWNER;

typedef struct {
    char *filename, *ptr;
    int32_t  length, num, soundsiz;
    SOUNDOWNER SoundOwner[4];
    int16_t ps,pe,vo;
    char pr,m;
    char lock;
    char *definedname;  // new
} sound_t;

#define MAXSOUNDS 4096
extern sound_t g_sounds[MAXSOUNDS];

extern int32_t g_numEnvSoundsPlaying;
extern int32_t NumVoices;

int32_t S_SoundStartup(void);
void S_SoundShutdown(void);
int32_t S_PlaySound3D(int32_t, int32_t, const vec3_t*);
void S_PlaySound(int32_t);
int32_t A_PlaySound(uint32_t num, int32_t i);
void S_StopSound(int32_t num);
void S_StopEnvSound(int32_t num,int32_t i);
void S_StopAllSounds(void);
void S_Update(void);
int32_t A_CheckSoundPlaying(int32_t i, int32_t num);
int32_t S_CheckSoundPlaying(int32_t i, int32_t num);
void S_ClearSoundLocks(void);
int32_t S_SoundsPlaying(int32_t i);
int32_t S_InvalidSound(int32_t num);
int32_t S_SoundFlags(int32_t num);

#pragma pack(pop)

#endif


code:
//-------------------------------------------------------------------------
/*
Copyright (C) 2013 EDuke32 developers and contributors

This file is part of EDuke32.

EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
//-------------------------------------------------------------------------

#include "compat.h"
#include "build.h"

#include "namesdyn.h"
#include "sounds.h"
#include "soundsdyn.h"
#include "global.h"

#ifdef DYNSOUNDREMAP_ENABLE
# define DVPTR(x) &x
#else
# define DVPTR(x) NULL
#endif

int16_t DynamicSoundMap[MAXSOUNDS];

struct sdynitem
{
    const char *str;
    int32_t *dynvalptr;
    const int16_t staticval;
};

static struct sdynitem g_dynSoundList[] =
{
    { "KICK_HIT", DVPTR(KICK_HIT), KICK_HIT__STATIC },
    { "PISTOL_RICOCHET", DVPTR(PISTOL_RICOCHET), PISTOL_RICOCHET__STATIC },
    { "PISTOL_BODYHIT", DVPTR(PISTOL_BODYHIT), PISTOL_BODYHIT__STATIC },
    { "PISTOL_FIRE", DVPTR(PISTOL_FIRE), PISTOL_FIRE__STATIC },
    { "EJECT_CLIP", DVPTR(EJECT_CLIP), EJECT_CLIP__STATIC },
    { "INSERT_CLIP", DVPTR(INSERT_CLIP), INSERT_CLIP__STATIC },
    { "CHAINGUN_FIRE", DVPTR(CHAINGUN_FIRE), CHAINGUN_FIRE__STATIC },
    { "RPG_SHOOT", DVPTR(RPG_SHOOT), RPG_SHOOT__STATIC },
    { "POOLBALLHIT", DVPTR(POOLBALLHIT), POOLBALLHIT__STATIC },
    { "RPG_EXPLODE", DVPTR(RPG_EXPLODE), RPG_EXPLODE__STATIC },
    { "CAT_FIRE", DVPTR(CAT_FIRE), CAT_FIRE__STATIC },
    { "SHRINKER_FIRE", DVPTR(SHRINKER_FIRE), SHRINKER_FIRE__STATIC },
    { "PIPEBOMB_BOUNCE", DVPTR(PIPEBOMB_BOUNCE), PIPEBOMB_BOUNCE__STATIC },
    { "PIPEBOMB_EXPLODE", DVPTR(PIPEBOMB_EXPLODE), PIPEBOMB_EXPLODE__STATIC },
    { "LASERTRIP_ONWALL", DVPTR(LASERTRIP_ONWALL), LASERTRIP_ONWALL__STATIC },
    { "LASERTRIP_ARMING", DVPTR(LASERTRIP_ARMING), LASERTRIP_ARMING__STATIC },
    { "LASERTRIP_EXPLODE", DVPTR(LASERTRIP_EXPLODE), LASERTRIP_EXPLODE__STATIC },
    { "VENT_BUST", DVPTR(VENT_BUST), VENT_BUST__STATIC },
    { "GLASS_BREAKING", DVPTR(GLASS_BREAKING), GLASS_BREAKING__STATIC },
    { "GLASS_HEAVYBREAK", DVPTR(GLASS_HEAVYBREAK), GLASS_HEAVYBREAK__STATIC },
    { "SHORT_CIRCUIT", DVPTR(SHORT_CIRCUIT), SHORT_CIRCUIT__STATIC },
    { "ITEM_SPLASH", DVPTR(ITEM_SPLASH), ITEM_SPLASH__STATIC },
    { "DUKE_GASP", DVPTR(DUKE_GASP), DUKE_GASP__STATIC },
    { "SLIM_RECOG", DVPTR(SLIM_RECOG), SLIM_RECOG__STATIC },
    { "DUKE_URINATE", DVPTR(DUKE_URINATE), DUKE_URINATE__STATIC },
    { "ENDSEQVOL3SND2", DVPTR(ENDSEQVOL3SND2), ENDSEQVOL3SND2__STATIC },
    { "ENDSEQVOL3SND3", DVPTR(ENDSEQVOL3SND3), ENDSEQVOL3SND3__STATIC },
    { "DUKE_CRACK", DVPTR(DUKE_CRACK), DUKE_CRACK__STATIC },
    { "SLIM_ATTACK", DVPTR(SLIM_ATTACK), SLIM_ATTACK__STATIC },
    { "SOMETHINGHITFORCE", DVPTR(SOMETHINGHITFORCE), SOMETHINGHITFORCE__STATIC },
    { "DUKE_DRINKING", DVPTR(DUKE_DRINKING), DUKE_DRINKING__STATIC },
    { "DUKE_GRUNT", DVPTR(DUKE_GRUNT), DUKE_GRUNT__STATIC },
    { "DUKE_HARTBEAT", DVPTR(DUKE_HARTBEAT), DUKE_HARTBEAT__STATIC },
    { "DUKE_ONWATER", DVPTR(DUKE_ONWATER), DUKE_ONWATER__STATIC },
    { "DUKE_LAND", DVPTR(DUKE_LAND), DUKE_LAND__STATIC },
    { "DUKE_WALKINDUCTS", DVPTR(DUKE_WALKINDUCTS), DUKE_WALKINDUCTS__STATIC },
    { "DUKE_UNDERWATER", DVPTR(DUKE_UNDERWATER), DUKE_UNDERWATER__STATIC },
    { "DUKE_JETPACK_ON", DVPTR(DUKE_JETPACK_ON), DUKE_JETPACK_ON__STATIC },
    { "DUKE_JETPACK_IDLE", DVPTR(DUKE_JETPACK_IDLE), DUKE_JETPACK_IDLE__STATIC },
    { "DUKE_JETPACK_OFF", DVPTR(DUKE_JETPACK_OFF), DUKE_JETPACK_OFF__STATIC },
    { "DUKETALKTOBOSS", DVPTR(DUKETALKTOBOSS), DUKETALKTOBOSS__STATIC },
    { "SQUISHED", DVPTR(SQUISHED), SQUISHED__STATIC },
    { "TELEPORTER", DVPTR(TELEPORTER), TELEPORTER__STATIC },
    { "ELEVATOR_ON", DVPTR(ELEVATOR_ON), ELEVATOR_ON__STATIC },
    { "ELEVATOR_OFF", DVPTR(ELEVATOR_OFF), ELEVATOR_OFF__STATIC },
    { "SUBWAY", DVPTR(SUBWAY), SUBWAY__STATIC },
    { "SWITCH_ON", DVPTR(SWITCH_ON), SWITCH_ON__STATIC },
    { "FLUSH_TOILET", DVPTR(FLUSH_TOILET), FLUSH_TOILET__STATIC },
    { "EARTHQUAKE", DVPTR(EARTHQUAKE), EARTHQUAKE__STATIC },
    { "END_OF_LEVEL_WARN", DVPTR(END_OF_LEVEL_WARN), END_OF_LEVEL_WARN__STATIC },
    { "WIND_AMBIENCE", DVPTR(WIND_AMBIENCE), WIND_AMBIENCE__STATIC },
    { "SOMETHING_DRIPPING", DVPTR(SOMETHING_DRIPPING), SOMETHING_DRIPPING__STATIC },
    { "BOS1_RECOG", DVPTR(BOS1_RECOG), BOS1_RECOG__STATIC },
    { "BOS2_RECOG", DVPTR(BOS2_RECOG), BOS2_RECOG__STATIC },
    { "DUKE_GETWEAPON2", DVPTR(DUKE_GETWEAPON2), DUKE_GETWEAPON2__STATIC },
    { "SHOTGUN_FIRE", DVPTR(SHOTGUN_FIRE), SHOTGUN_FIRE__STATIC },
    { "PRED_RECOG", DVPTR(PRED_RECOG), PRED_RECOG__STATIC },
    { "CAPT_RECOG", DVPTR(CAPT_RECOG), CAPT_RECOG__STATIC },
    { "PIG_RECOG", DVPTR(PIG_RECOG), PIG_RECOG__STATIC },
    { "RECO_ROAM", DVPTR(RECO_ROAM), RECO_ROAM__STATIC },
    { "RECO_RECOG", DVPTR(RECO_RECOG), RECO_RECOG__STATIC },
    { "RECO_ATTACK", DVPTR(RECO_ATTACK), RECO_ATTACK__STATIC },
    { "RECO_PAIN", DVPTR(RECO_PAIN), RECO_PAIN__STATIC },
    { "DRON_RECOG", DVPTR(DRON_RECOG), DRON_RECOG__STATIC },
    { "COMM_RECOG", DVPTR(COMM_RECOG), COMM_RECOG__STATIC },
    { "OCTA_RECOG", DVPTR(OCTA_RECOG), OCTA_RECOG__STATIC },
    { "TURR_RECOG", DVPTR(TURR_RECOG), TURR_RECOG__STATIC },
    { "SLIM_DYING", DVPTR(SLIM_DYING), SLIM_DYING__STATIC },
    { "BOS3_RECOG", DVPTR(BOS3_RECOG), BOS3_RECOG__STATIC },
    { "BOS1_WALK", DVPTR(BOS1_WALK), BOS1_WALK__STATIC },
    { "THUD", DVPTR(THUD), THUD__STATIC },
    { "WIERDSHOT_FLY", DVPTR(WIERDSHOT_FLY), WIERDSHOT_FLY__STATIC },
    { "SLIM_ROAM", DVPTR(SLIM_ROAM), SLIM_ROAM__STATIC },
    { "SHOTGUN_COCK", DVPTR(SHOTGUN_COCK), SHOTGUN_COCK__STATIC },
    { "GENERIC_AMBIENCE17", DVPTR(GENERIC_AMBIENCE17), GENERIC_AMBIENCE17__STATIC },
    { "BONUS_SPEECH1", DVPTR(BONUS_SPEECH1), BONUS_SPEECH1__STATIC },
    { "BONUS_SPEECH2", DVPTR(BONUS_SPEECH2), BONUS_SPEECH2__STATIC },
    { "BONUS_SPEECH3", DVPTR(BONUS_SPEECH3), BONUS_SPEECH3__STATIC },
    { "BONUS_SPEECH4", DVPTR(BONUS_SPEECH4), BONUS_SPEECH4__STATIC },
    { "DUKE_LAND_HURT", DVPTR(DUKE_LAND_HURT), DUKE_LAND_HURT__STATIC },
    { "DUKE_SEARCH2", DVPTR(DUKE_SEARCH2), DUKE_SEARCH2__STATIC },
    { "DUKE_CRACK2", DVPTR(DUKE_CRACK2), DUKE_CRACK2__STATIC },
    { "DUKE_SEARCH", DVPTR(DUKE_SEARCH), DUKE_SEARCH__STATIC },
    { "DUKE_GET", DVPTR(DUKE_GET), DUKE_GET__STATIC },
    { "DUKE_LONGTERM_PAIN", DVPTR(DUKE_LONGTERM_PAIN), DUKE_LONGTERM_PAIN__STATIC },
    { "MONITOR_ACTIVE", DVPTR(MONITOR_ACTIVE), MONITOR_ACTIVE__STATIC },
    { "NITEVISION_ONOFF", DVPTR(NITEVISION_ONOFF), NITEVISION_ONOFF__STATIC },
    { "DUKE_CRACK_FIRST", DVPTR(DUKE_CRACK_FIRST), DUKE_CRACK_FIRST__STATIC },
    { "DUKE_USEMEDKIT", DVPTR(DUKE_USEMEDKIT), DUKE_USEMEDKIT__STATIC },
    { "DUKE_TAKEPILLS", DVPTR(DUKE_TAKEPILLS), DUKE_TAKEPILLS__STATIC },
    { "DUKE_PISSRELIEF", DVPTR(DUKE_PISSRELIEF), DUKE_PISSRELIEF__STATIC },
    { "SELECT_WEAPON", DVPTR(SELECT_WEAPON), SELECT_WEAPON__STATIC },
    { "JIBBED_ACTOR5", DVPTR(JIBBED_ACTOR5), JIBBED_ACTOR5__STATIC },
    { "JIBBED_ACTOR6", DVPTR(JIBBED_ACTOR6), JIBBED_ACTOR6__STATIC },
    { "DUKE_GOTHEALTHATLOW", DVPTR(DUKE_GOTHEALTHATLOW), DUKE_GOTHEALTHATLOW__STATIC },
    { "BOSSTALKTODUKE", DVPTR(BOSSTALKTODUKE), BOSSTALKTODUKE__STATIC },
    { "WAR_AMBIENCE2", DVPTR(WAR_AMBIENCE2), WAR_AMBIENCE2__STATIC },
    { "EXITMENUSOUND", DVPTR(EXITMENUSOUND), EXITMENUSOUND__STATIC },
    { "FLY_BY", DVPTR(FLY_BY), FLY_BY__STATIC },
    { "DUKE_SCREAM", DVPTR(DUKE_SCREAM), DUKE_SCREAM__STATIC },
    { "SHRINKER_HIT", DVPTR(SHRINKER_HIT), SHRINKER_HIT__STATIC },
    { "RATTY", DVPTR(RATTY), RATTY__STATIC },
    { "BONUSMUSIC", DVPTR(BONUSMUSIC), BONUSMUSIC__STATIC },
    { "DUKE_GETWEAPON6", DVPTR(DUKE_GETWEAPON6), DUKE_GETWEAPON6__STATIC },
    { "ALIEN_SWITCH1", DVPTR(ALIEN_SWITCH1), ALIEN_SWITCH1__STATIC },
    { "RIPHEADNECK", DVPTR(RIPHEADNECK), RIPHEADNECK__STATIC },
    { "ENDSEQVOL3SND4", DVPTR(ENDSEQVOL3SND4), ENDSEQVOL3SND4__STATIC },
    { "ENDSEQVOL3SND5", DVPTR(ENDSEQVOL3SND5), ENDSEQVOL3SND5__STATIC },
    { "ENDSEQVOL3SND6", DVPTR(ENDSEQVOL3SND6), ENDSEQVOL3SND6__STATIC },
    { "ENDSEQVOL3SND7", DVPTR(ENDSEQVOL3SND7), ENDSEQVOL3SND7__STATIC },
    { "ENDSEQVOL3SND8", DVPTR(ENDSEQVOL3SND8), ENDSEQVOL3SND8__STATIC },
    { "ENDSEQVOL3SND9", DVPTR(ENDSEQVOL3SND9), ENDSEQVOL3SND9__STATIC },
    { "WHIPYOURASS", DVPTR(WHIPYOURASS), WHIPYOURASS__STATIC },
    { "ENDSEQVOL2SND1", DVPTR(ENDSEQVOL2SND1), ENDSEQVOL2SND1__STATIC },
    { "ENDSEQVOL2SND2", DVPTR(ENDSEQVOL2SND2), ENDSEQVOL2SND2__STATIC },
    { "ENDSEQVOL2SND3", DVPTR(ENDSEQVOL2SND3), ENDSEQVOL2SND3__STATIC },
    { "ENDSEQVOL2SND4", DVPTR(ENDSEQVOL2SND4), ENDSEQVOL2SND4__STATIC },
    { "ENDSEQVOL2SND5", DVPTR(ENDSEQVOL2SND5), ENDSEQVOL2SND5__STATIC },
    { "ENDSEQVOL2SND6", DVPTR(ENDSEQVOL2SND6), ENDSEQVOL2SND6__STATIC },
    { "ENDSEQVOL2SND7", DVPTR(ENDSEQVOL2SND7), ENDSEQVOL2SND7__STATIC },
    { "SOMETHINGFROZE", DVPTR(SOMETHINGFROZE), SOMETHINGFROZE__STATIC },
    { "WIND_REPEAT", DVPTR(WIND_REPEAT), WIND_REPEAT__STATIC },
    { "BOS4_RECOG", DVPTR(BOS4_RECOG), BOS4_RECOG__STATIC },
    { "LIGHTNING_SLAP", DVPTR(LIGHTNING_SLAP), LIGHTNING_SLAP__STATIC },
    { "THUNDER", DVPTR(THUNDER), THUNDER__STATIC },
    { "INTRO4_1", DVPTR(INTRO4_1), INTRO4_1__STATIC },
    { "INTRO4_2", DVPTR(INTRO4_2), INTRO4_2__STATIC },
    { "INTRO4_3", DVPTR(INTRO4_3), INTRO4_3__STATIC },
    { "INTRO4_4", DVPTR(INTRO4_4), INTRO4_4__STATIC },
    { "INTRO4_5", DVPTR(INTRO4_5), INTRO4_5__STATIC },
    { "INTRO4_6", DVPTR(INTRO4_6), INTRO4_6__STATIC },
    { "BOSS4_DEADSPEECH", DVPTR(BOSS4_DEADSPEECH), BOSS4_DEADSPEECH__STATIC },
    { "BOSS4_FIRSTSEE", DVPTR(BOSS4_FIRSTSEE), BOSS4_FIRSTSEE__STATIC },
    { "VOL4ENDSND1", DVPTR(VOL4ENDSND1), VOL4ENDSND1__STATIC },
    { "VOL4ENDSND2", DVPTR(VOL4ENDSND2), VOL4ENDSND2__STATIC },
    { "EXPANDERSHOOT", DVPTR(EXPANDERSHOOT), EXPANDERSHOOT__STATIC },
    { "INTRO4_B", DVPTR(INTRO4_B), INTRO4_B__STATIC },
    { "BIGBANG", DVPTR(BIGBANG), BIGBANG__STATIC },
    { NULL, NULL, -1 },
 };

#ifdef DYNSOUNDREMAP_ENABLE

int32_t KICK_HIT = KICK_HIT__STATIC;
int32_t PISTOL_RICOCHET = PISTOL_RICOCHET__STATIC;
int32_t PISTOL_BODYHIT = PISTOL_BODYHIT__STATIC;
int32_t PISTOL_FIRE = PISTOL_FIRE__STATIC;
int32_t EJECT_CLIP = EJECT_CLIP__STATIC;
int32_t INSERT_CLIP = INSERT_CLIP__STATIC;
int32_t CHAINGUN_FIRE = CHAINGUN_FIRE__STATIC;
int32_t RPG_SHOOT = RPG_SHOOT__STATIC;
int32_t POOLBALLHIT = POOLBALLHIT__STATIC;
int32_t RPG_EXPLODE = RPG_EXPLODE__STATIC;
int32_t CAT_FIRE = CAT_FIRE__STATIC;
int32_t SHRINKER_FIRE = SHRINKER_FIRE__STATIC;
int32_t PIPEBOMB_BOUNCE = PIPEBOMB_BOUNCE__STATIC;
int32_t PIPEBOMB_EXPLODE = PIPEBOMB_EXPLODE__STATIC;
int32_t LASERTRIP_ONWALL = LASERTRIP_ONWALL__STATIC;
int32_t LASERTRIP_ARMING = LASERTRIP_ARMING__STATIC;
int32_t LASERTRIP_EXPLODE = LASERTRIP_EXPLODE__STATIC;
int32_t VENT_BUST = VENT_BUST__STATIC;
int32_t GLASS_BREAKING = GLASS_BREAKING__STATIC;
int32_t GLASS_HEAVYBREAK = GLASS_HEAVYBREAK__STATIC;
int32_t SHORT_CIRCUIT = SHORT_CIRCUIT__STATIC;
int32_t ITEM_SPLASH = ITEM_SPLASH__STATIC;
int32_t DUKE_GASP = DUKE_GASP__STATIC;
int32_t SLIM_RECOG = SLIM_RECOG__STATIC;
int32_t DUKE_URINATE = DUKE_URINATE__STATIC;
int32_t ENDSEQVOL3SND2 = ENDSEQVOL3SND2__STATIC;
int32_t ENDSEQVOL3SND3 = ENDSEQVOL3SND3__STATIC;
int32_t DUKE_CRACK = DUKE_CRACK__STATIC;
int32_t SLIM_ATTACK = SLIM_ATTACK__STATIC;
int32_t SOMETHINGHITFORCE = SOMETHINGHITFORCE__STATIC;
int32_t DUKE_DRINKING = DUKE_DRINKING__STATIC;
int32_t DUKE_GRUNT = DUKE_GRUNT__STATIC;
int32_t DUKE_HARTBEAT = DUKE_HARTBEAT__STATIC;
int32_t DUKE_ONWATER = DUKE_ONWATER__STATIC;
int32_t DUKE_LAND = DUKE_LAND__STATIC;
int32_t DUKE_WALKINDUCTS = DUKE_WALKINDUCTS__STATIC;
int32_t DUKE_UNDERWATER = DUKE_UNDERWATER__STATIC;
int32_t DUKE_JETPACK_ON = DUKE_JETPACK_ON__STATIC;
int32_t DUKE_JETPACK_IDLE = DUKE_JETPACK_IDLE__STATIC;
int32_t DUKE_JETPACK_OFF = DUKE_JETPACK_OFF__STATIC;
int32_t DUKETALKTOBOSS = DUKETALKTOBOSS__STATIC;
int32_t SQUISHED = SQUISHED__STATIC;
int32_t TELEPORTER = TELEPORTER__STATIC;
int32_t ELEVATOR_ON = ELEVATOR_ON__STATIC;
int32_t ELEVATOR_OFF = ELEVATOR_OFF__STATIC;
int32_t SUBWAY = SUBWAY__STATIC;
int32_t SWITCH_ON = SWITCH_ON__STATIC;
int32_t FLUSH_TOILET = FLUSH_TOILET__STATIC;
int32_t EARTHQUAKE = EARTHQUAKE__STATIC;
int32_t END_OF_LEVEL_WARN = END_OF_LEVEL_WARN__STATIC;
int32_t WIND_AMBIENCE = WIND_AMBIENCE__STATIC;
int32_t SOMETHING_DRIPPING = SOMETHING_DRIPPING__STATIC;
int32_t BOS1_RECOG = BOS1_RECOG__STATIC;
int32_t BOS2_RECOG = BOS2_RECOG__STATIC;
int32_t DUKE_GETWEAPON2 = DUKE_GETWEAPON2__STATIC;
int32_t SHOTGUN_FIRE = SHOTGUN_FIRE__STATIC;
int32_t PRED_RECOG = PRED_RECOG__STATIC;
int32_t CAPT_RECOG = CAPT_RECOG__STATIC;
int32_t PIG_RECOG = PIG_RECOG__STATIC;
int32_t RECO_ROAM = RECO_ROAM__STATIC;
int32_t RECO_RECOG = RECO_RECOG__STATIC;
int32_t RECO_ATTACK = RECO_ATTACK__STATIC;
int32_t RECO_PAIN = RECO_PAIN__STATIC;
int32_t DRON_RECOG = DRON_RECOG__STATIC;
int32_t COMM_RECOG = COMM_RECOG__STATIC;
int32_t OCTA_RECOG = OCTA_RECOG__STATIC;
int32_t TURR_RECOG = TURR_RECOG__STATIC;
int32_t SLIM_DYING = SLIM_DYING__STATIC;
int32_t BOS3_RECOG = BOS3_RECOG__STATIC;
int32_t BOS1_WALK = BOS1_WALK__STATIC;
int32_t THUD = THUD__STATIC;
int32_t WIERDSHOT_FLY = WIERDSHOT_FLY__STATIC;
int32_t SLIM_ROAM = SLIM_ROAM__STATIC;
int32_t SHOTGUN_COCK = SHOTGUN_COCK__STATIC;
int32_t GENERIC_AMBIENCE17 = GENERIC_AMBIENCE17__STATIC;
int32_t BONUS_SPEECH1 = BONUS_SPEECH1__STATIC;
int32_t BONUS_SPEECH2 = BONUS_SPEECH2__STATIC;
int32_t BONUS_SPEECH3 = BONUS_SPEECH3__STATIC;
int32_t BONUS_SPEECH4 = BONUS_SPEECH4__STATIC;
int32_t DUKE_LAND_HURT = DUKE_LAND_HURT__STATIC;
int32_t DUKE_SEARCH2 = DUKE_SEARCH2__STATIC;
int32_t DUKE_CRACK2 = DUKE_CRACK2__STATIC;
int32_t DUKE_SEARCH = DUKE_SEARCH__STATIC;
int32_t DUKE_GET = DUKE_GET__STATIC;
int32_t DUKE_LONGTERM_PAIN = DUKE_LONGTERM_PAIN__STATIC;
int32_t MONITOR_ACTIVE = MONITOR_ACTIVE__STATIC;
int32_t NITEVISION_ONOFF = NITEVISION_ONOFF__STATIC;
int32_t DUKE_CRACK_FIRST = DUKE_CRACK_FIRST__STATIC;
int32_t DUKE_USEMEDKIT = DUKE_USEMEDKIT__STATIC;
int32_t DUKE_TAKEPILLS = DUKE_TAKEPILLS__STATIC;
int32_t DUKE_PISSRELIEF = DUKE_PISSRELIEF__STATIC;
int32_t SELECT_WEAPON = SELECT_WEAPON__STATIC;
int32_t JIBBED_ACTOR5 = JIBBED_ACTOR5__STATIC;
int32_t JIBBED_ACTOR6 = JIBBED_ACTOR6__STATIC;
int32_t DUKE_GOTHEALTHATLOW = DUKE_GOTHEALTHATLOW__STATIC;
int32_t BOSSTALKTODUKE = BOSSTALKTODUKE__STATIC;
int32_t WAR_AMBIENCE2 = WAR_AMBIENCE2__STATIC;
int32_t EXITMENUSOUND = EXITMENUSOUND__STATIC;
int32_t FLY_BY = FLY_BY__STATIC;
int32_t DUKE_SCREAM = DUKE_SCREAM__STATIC;
int32_t SHRINKER_HIT = SHRINKER_HIT__STATIC;
int32_t RATTY = RATTY__STATIC;
int32_t BONUSMUSIC = BONUSMUSIC__STATIC;
int32_t DUKE_GETWEAPON6 = DUKE_GETWEAPON6__STATIC;
int32_t ALIEN_SWITCH1 = ALIEN_SWITCH1__STATIC;
int32_t RIPHEADNECK = RIPHEADNECK__STATIC;
int32_t ENDSEQVOL3SND4 = ENDSEQVOL3SND4__STATIC;
int32_t ENDSEQVOL3SND5 = ENDSEQVOL3SND5__STATIC;
int32_t ENDSEQVOL3SND6 = ENDSEQVOL3SND6__STATIC;
int32_t ENDSEQVOL3SND7 = ENDSEQVOL3SND7__STATIC;
int32_t ENDSEQVOL3SND8 = ENDSEQVOL3SND8__STATIC;
int32_t ENDSEQVOL3SND9 = ENDSEQVOL3SND9__STATIC;
int32_t WHIPYOURASS = WHIPYOURASS__STATIC;
int32_t ENDSEQVOL2SND1 = ENDSEQVOL2SND1__STATIC;
int32_t ENDSEQVOL2SND2 = ENDSEQVOL2SND2__STATIC;
int32_t ENDSEQVOL2SND3 = ENDSEQVOL2SND3__STATIC;
int32_t ENDSEQVOL2SND4 = ENDSEQVOL2SND4__STATIC;
int32_t ENDSEQVOL2SND5 = ENDSEQVOL2SND5__STATIC;
int32_t ENDSEQVOL2SND6 = ENDSEQVOL2SND6__STATIC;
int32_t ENDSEQVOL2SND7 = ENDSEQVOL2SND7__STATIC;
int32_t SOMETHINGFROZE = SOMETHINGFROZE__STATIC;
int32_t WIND_REPEAT = WIND_REPEAT__STATIC;
int32_t BOS4_RECOG = BOS4_RECOG__STATIC;
int32_t LIGHTNING_SLAP = LIGHTNING_SLAP__STATIC;
int32_t THUNDER = THUNDER__STATIC;
int32_t INTRO4_1 = INTRO4_1__STATIC;
int32_t INTRO4_2 = INTRO4_2__STATIC;
int32_t INTRO4_3 = INTRO4_3__STATIC;
int32_t INTRO4_4 = INTRO4_4__STATIC;
int32_t INTRO4_5 = INTRO4_5__STATIC;
int32_t INTRO4_6 = INTRO4_6__STATIC;
int32_t BOSS4_DEADSPEECH = BOSS4_DEADSPEECH__STATIC;
int32_t BOSS4_FIRSTSEE = BOSS4_FIRSTSEE__STATIC;
int32_t VOL4ENDSND1 = VOL4ENDSND1__STATIC;
int32_t VOL4ENDSND2 = VOL4ENDSND2__STATIC;
int32_t EXPANDERSHOOT = EXPANDERSHOOT__STATIC;
int32_t INTRO4_B = INTRO4_B__STATIC;
int32_t BIGBANG = BIGBANG__STATIC;

static hashtable_t h_names = {512, NULL};

void G_ProcessDynamicSoundMapping(const char *szLabel, int32_t lValue)
{
    int32_t i;

    if ((unsigned)lValue >= MAXSOUNDS || !szLabel)
        return;

    i = hash_find(&h_names,szLabel);
    if (i>=0)
    {
        struct sdynitem *di = &g_dynSoundList[i];
#ifdef DEBUGGINGAIDS
        if (g_scriptDebug && di->staticval != lValue)
            OSD_Printf("REMAP %s (%d) --> %d\n", di->str, di->staticval, lValue);
#endif
        *di->dynvalptr = lValue;
    }
}

void initsoundhashnames(void)
{
    int32_t i;

    hash_init(&h_names);

    for (i=0; g_dynSoundList[i].staticval >= 0; i++)
        hash_add(&h_names, g_dynSoundList[i].str, i, 0);
}

void freesoundhashnames(void)
{
    hash_free(&h_names);
}
#endif

// This is run after all CON define's have been processed to set up the
// dynamic->static sound mapping.
void G_InitDynamicSounds(void)
{
    int32_t i;

    Bmemset(DynamicSoundMap, 0, sizeof(DynamicSoundMap));

    for (i=0; g_dynSoundList[i].staticval >= 0; i++)
#ifdef DYNSOUNDREMAP_ENABLE
        DynamicSoundMap[*(g_dynSoundList[i].dynvalptr)] = g_dynSoundList[i].staticval;
#else
        DynamicSoundMap[g_dynSoundList[i].staticval] = g_dynSoundList[i].staticval;
#endif

}


code:
//-------------------------------------------------------------------------
/*
Copyright (C) 2013 EDuke32 developers and contributors

This file is part of EDuke32.

EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
//-------------------------------------------------------------------------

#define DYNSOUNDREMAP_ENABLE

#define KICK_HIT__STATIC 0
#define PISTOL_RICOCHET__STATIC 1
#define PISTOL_BODYHIT__STATIC 2
#define PISTOL_FIRE__STATIC 3
#define EJECT_CLIP__STATIC 4
#define INSERT_CLIP__STATIC 5
#define CHAINGUN_FIRE__STATIC 6
#define RPG_SHOOT__STATIC 7
#define POOLBALLHIT__STATIC 8
#define RPG_EXPLODE__STATIC 9
#define CAT_FIRE__STATIC 10
#define SHRINKER_FIRE__STATIC 11
#define PIPEBOMB_BOUNCE__STATIC 13
#define PIPEBOMB_EXPLODE__STATIC 14
#define LASERTRIP_ONWALL__STATIC 15
#define LASERTRIP_ARMING__STATIC 16
#define LASERTRIP_EXPLODE__STATIC 17
#define VENT_BUST__STATIC 18
#define GLASS_BREAKING__STATIC 19
#define GLASS_HEAVYBREAK__STATIC 20
#define SHORT_CIRCUIT__STATIC 21
#define ITEM_SPLASH__STATIC 22
#define DUKE_GASP__STATIC 25
#define SLIM_RECOG__STATIC 26
#define DUKE_URINATE__STATIC 28
#define ENDSEQVOL3SND2__STATIC 29
#define ENDSEQVOL3SND3__STATIC 30
#define DUKE_CRACK__STATIC 33
#define SLIM_ATTACK__STATIC 34
#define SOMETHINGHITFORCE__STATIC 35
#define DUKE_DRINKING__STATIC 36
#define DUKE_GRUNT__STATIC 38
#define DUKE_HARTBEAT__STATIC 39
#define DUKE_ONWATER__STATIC 40
#define DUKE_LAND__STATIC 42
#define DUKE_WALKINDUCTS__STATIC 43
#define DUKE_UNDERWATER__STATIC 48
#define DUKE_JETPACK_ON__STATIC 49
#define DUKE_JETPACK_IDLE__STATIC 50
#define DUKE_JETPACK_OFF__STATIC 51
#define DUKETALKTOBOSS__STATIC 56
#define SQUISHED__STATIC 69
#define TELEPORTER__STATIC 70
#define ELEVATOR_ON__STATIC 71
#define ELEVATOR_OFF__STATIC 73
#define SUBWAY__STATIC 75
#define SWITCH_ON__STATIC 76
#define FLUSH_TOILET__STATIC 79
#define EARTHQUAKE__STATIC 81
#define END_OF_LEVEL_WARN__STATIC 83
#define WIND_AMBIENCE__STATIC 91
#define SOMETHING_DRIPPING__STATIC 92
#define BOS1_RECOG__STATIC 97
#define BOS2_RECOG__STATIC 102
#define DUKE_GETWEAPON2__STATIC 107
#define SHOTGUN_FIRE__STATIC 109
#define PRED_RECOG__STATIC 111
#define CAPT_RECOG__STATIC 117
#define PIG_RECOG__STATIC 121
#define RECO_ROAM__STATIC 125
#define RECO_RECOG__STATIC 126
#define RECO_ATTACK__STATIC 127
#define RECO_PAIN__STATIC 128
#define DRON_RECOG__STATIC 131
#define COMM_RECOG__STATIC 136
#define OCTA_RECOG__STATIC 141
#define TURR_RECOG__STATIC 146
#define SLIM_DYING__STATIC 149
#define BOS3_RECOG__STATIC 151
#define BOS1_WALK__STATIC 156
#define THUD__STATIC 158
#define WIERDSHOT_FLY__STATIC 160
#define SLIM_ROAM__STATIC 163
#define SHOTGUN_COCK__STATIC 169
#define GENERIC_AMBIENCE17__STATIC 177
#define BONUS_SPEECH1__STATIC 195
#define BONUS_SPEECH2__STATIC 196
#define BONUS_SPEECH3__STATIC 197
#define BONUS_SPEECH4__STATIC 199
#define DUKE_LAND_HURT__STATIC 200
#define DUKE_SEARCH2__STATIC 207
#define DUKE_CRACK2__STATIC 208
#define DUKE_SEARCH__STATIC 209
#define DUKE_GET__STATIC 210
#define DUKE_LONGTERM_PAIN__STATIC 211
#define MONITOR_ACTIVE__STATIC 212
#define NITEVISION_ONOFF__STATIC 213
#define DUKE_CRACK_FIRST__STATIC 215
#define DUKE_USEMEDKIT__STATIC 216
#define DUKE_TAKEPILLS__STATIC 217
#define DUKE_PISSRELIEF__STATIC 218
#define SELECT_WEAPON__STATIC 219
#define JIBBED_ACTOR5__STATIC 226
#define JIBBED_ACTOR6__STATIC 227
#define DUKE_GOTHEALTHATLOW__STATIC 229
#define BOSSTALKTODUKE__STATIC 230
#define WAR_AMBIENCE2__STATIC 232
#define EXITMENUSOUND__STATIC 243
#define FLY_BY__STATIC 244
#define DUKE_SCREAM__STATIC 245
#define SHRINKER_HIT__STATIC 246
#define RATTY__STATIC 247
#define BONUSMUSIC__STATIC 249
#define DUKE_GETWEAPON6__STATIC 264
#define ALIEN_SWITCH1__STATIC 272
#define RIPHEADNECK__STATIC 284
#define ENDSEQVOL3SND4__STATIC 288
#define ENDSEQVOL3SND5__STATIC 289
#define ENDSEQVOL3SND6__STATIC 290
#define ENDSEQVOL3SND7__STATIC 291
#define ENDSEQVOL3SND8__STATIC 292
#define ENDSEQVOL3SND9__STATIC 293
#define WHIPYOURASS__STATIC 294
#define ENDSEQVOL2SND1__STATIC 295
#define ENDSEQVOL2SND2__STATIC 296
#define ENDSEQVOL2SND3__STATIC 297
#define ENDSEQVOL2SND4__STATIC 298
#define ENDSEQVOL2SND5__STATIC 299
#define ENDSEQVOL2SND6__STATIC 300
#define ENDSEQVOL2SND7__STATIC 301
#define SOMETHINGFROZE__STATIC 303
#define WIND_REPEAT__STATIC 308
#define BOS4_RECOG__STATIC 342
#define LIGHTNING_SLAP__STATIC 351
#define THUNDER__STATIC 352
#define INTRO4_1__STATIC 363
#define INTRO4_2__STATIC 364
#define INTRO4_3__STATIC 365
#define INTRO4_4__STATIC 366
#define INTRO4_5__STATIC 367
#define INTRO4_6__STATIC 368
#define BOSS4_DEADSPEECH__STATIC 370
#define BOSS4_FIRSTSEE__STATIC 371
#define VOL4ENDSND1__STATIC 384
#define VOL4ENDSND2__STATIC 385
#define EXPANDERSHOOT__STATIC 388
#define INTRO4_B__STATIC 392
#define BIGBANG__STATIC 393

extern int16_t DynamicSoundMap[MAXSOUNDS];

void G_InitDynamicSounds(void);

#ifdef DYNSOUNDREMAP_ENABLE

void G_ProcessDynamicSoundMapping(const char *szLabel, int32_t lValue);

void initsoundhashnames(void);
void freesoundhashnames(void);

extern int32_t KICK_HIT;
extern int32_t PISTOL_RICOCHET;
extern int32_t PISTOL_BODYHIT;
extern int32_t PISTOL_FIRE;
extern int32_t EJECT_CLIP;
extern int32_t INSERT_CLIP;
extern int32_t CHAINGUN_FIRE;
extern int32_t RPG_SHOOT;
extern int32_t POOLBALLHIT;
extern int32_t RPG_EXPLODE;
extern int32_t CAT_FIRE;
extern int32_t SHRINKER_FIRE;
extern int32_t PIPEBOMB_BOUNCE;
extern int32_t PIPEBOMB_EXPLODE;
extern int32_t LASERTRIP_ONWALL;
extern int32_t LASERTRIP_ARMING;
extern int32_t LASERTRIP_EXPLODE;
extern int32_t VENT_BUST;
extern int32_t GLASS_BREAKING;
extern int32_t GLASS_HEAVYBREAK;
extern int32_t SHORT_CIRCUIT;
extern int32_t ITEM_SPLASH;
extern int32_t DUKE_GASP;
extern int32_t SLIM_RECOG;
extern int32_t DUKE_URINATE;
extern int32_t ENDSEQVOL3SND2;
extern int32_t ENDSEQVOL3SND3;
extern int32_t DUKE_CRACK;
extern int32_t SLIM_ATTACK;
extern int32_t SOMETHINGHITFORCE;
extern int32_t DUKE_DRINKING;
extern int32_t DUKE_GRUNT;
extern int32_t DUKE_HARTBEAT;
extern int32_t DUKE_ONWATER;
extern int32_t DUKE_LAND;
extern int32_t DUKE_WALKINDUCTS;
extern int32_t DUKE_UNDERWATER;
extern int32_t DUKE_JETPACK_ON;
extern int32_t DUKE_JETPACK_IDLE;
extern int32_t DUKE_JETPACK_OFF;
extern int32_t DUKETALKTOBOSS;
extern int32_t SQUISHED;
extern int32_t TELEPORTER;
extern int32_t ELEVATOR_ON;
extern int32_t ELEVATOR_OFF;
extern int32_t SUBWAY;
extern int32_t SWITCH_ON;
extern int32_t FLUSH_TOILET;
extern int32_t EARTHQUAKE;
extern int32_t END_OF_LEVEL_WARN;
extern int32_t WIND_AMBIENCE;
extern int32_t SOMETHING_DRIPPING;
extern int32_t BOS1_RECOG;
extern int32_t BOS2_RECOG;
extern int32_t DUKE_GETWEAPON2;
extern int32_t SHOTGUN_FIRE;
extern int32_t PRED_RECOG;
extern int32_t CAPT_RECOG;
extern int32_t PIG_RECOG;
extern int32_t RECO_ROAM;
extern int32_t RECO_RECOG;
extern int32_t RECO_ATTACK;
extern int32_t RECO_PAIN;
extern int32_t DRON_RECOG;
extern int32_t COMM_RECOG;
extern int32_t OCTA_RECOG;
extern int32_t TURR_RECOG;
extern int32_t SLIM_DYING;
extern int32_t BOS3_RECOG;
extern int32_t BOS1_WALK;
extern int32_t THUD;
extern int32_t WIERDSHOT_FLY;
extern int32_t SLIM_ROAM;
extern int32_t SHOTGUN_COCK;
extern int32_t GENERIC_AMBIENCE17;
extern int32_t BONUS_SPEECH1;
extern int32_t BONUS_SPEECH2;
extern int32_t BONUS_SPEECH3;
extern int32_t BONUS_SPEECH4;
extern int32_t DUKE_LAND_HURT;
extern int32_t DUKE_SEARCH2;
extern int32_t DUKE_CRACK2;
extern int32_t DUKE_SEARCH;
extern int32_t DUKE_GET;
extern int32_t DUKE_LONGTERM_PAIN;
extern int32_t MONITOR_ACTIVE;
extern int32_t NITEVISION_ONOFF;
extern int32_t DUKE_CRACK_FIRST;
extern int32_t DUKE_USEMEDKIT;
extern int32_t DUKE_TAKEPILLS;
extern int32_t DUKE_PISSRELIEF;
extern int32_t SELECT_WEAPON;
extern int32_t JIBBED_ACTOR5;
extern int32_t JIBBED_ACTOR6;
extern int32_t DUKE_GOTHEALTHATLOW;
extern int32_t BOSSTALKTODUKE;
extern int32_t WAR_AMBIENCE2;
extern int32_t EXITMENUSOUND;
extern int32_t FLY_BY;
extern int32_t DUKE_SCREAM;
extern int32_t SHRINKER_HIT;
extern int32_t RATTY;
extern int32_t BONUSMUSIC;
extern int32_t DUKE_GETWEAPON6;
extern int32_t ALIEN_SWITCH1;
extern int32_t RIPHEADNECK;
extern int32_t ENDSEQVOL3SND4;
extern int32_t ENDSEQVOL3SND5;
extern int32_t ENDSEQVOL3SND6;
extern int32_t ENDSEQVOL3SND7;
extern int32_t ENDSEQVOL3SND8;
extern int32_t ENDSEQVOL3SND9;
extern int32_t WHIPYOURASS;
extern int32_t ENDSEQVOL2SND1;
extern int32_t ENDSEQVOL2SND2;
extern int32_t ENDSEQVOL2SND3;
extern int32_t ENDSEQVOL2SND4;
extern int32_t ENDSEQVOL2SND5;
extern int32_t ENDSEQVOL2SND6;
extern int32_t ENDSEQVOL2SND7;
extern int32_t SOMETHINGFROZE;
extern int32_t WIND_REPEAT;
extern int32_t BOS4_RECOG;
extern int32_t LIGHTNING_SLAP;
extern int32_t THUNDER;
extern int32_t INTRO4_1;
extern int32_t INTRO4_2;
extern int32_t INTRO4_3;
extern int32_t INTRO4_4;
extern int32_t INTRO4_5;
extern int32_t INTRO4_6;
extern int32_t BOSS4_DEADSPEECH;
extern int32_t BOSS4_FIRSTSEE;
extern int32_t VOL4ENDSND1;
extern int32_t VOL4ENDSND2;
extern int32_t EXPANDERSHOOT;
extern int32_t INTRO4_B;
extern int32_t BIGBANG;

#define DYNAMICSOUNDMAP(Soundnum) (DynamicSoundMap[Soundnum])

#else  /* if !defined DYNSOUNDREMAP_ENABLE */

#define G_ProcessDynamicSoundMapping(x, y) ((void)(0))

#define initsoundhashnames() ((void)0)
#define freesoundhashnames() ((void)0)

#include "soundefs.h"

#define DYNAMICSOUNDMAP(Soundnum) (Soundnum)

#endif