code:
//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
Copyright (C) 2017-2019 Nuke.YKT

This file is part of Duke Nukem 3D version 1.5 - Atomic Edition

Duke Nukem 3D is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

Original Source: 1996 - Todd Replogle
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------

// These tile positions are reserved!
#define RESERVEDSLOT1 6132
#define RESERVEDSLOT2 6133
#define RESERVEDSLOT3 6134
#define RESERVEDSLOT4 6135
#define RESERVEDSLOT5 6136
#define RESERVEDSLOT6 6137
#define RESERVEDSLOT7 6138
#define RESERVEDSLOT8 6139
#define RESERVEDSLOT9 6140
#define RESERVEDSLOT10 6141
#define RESERVEDSLOT11 6142
#define RESERVEDSLOT12 6143

// Defines weapon, not to be used with the 'shoot' keyword.

#define KNEE_WEAPON    0
#define PISTOL_WEAPON    1
#define SHOTGUN_WEAPON    2
#define CHAINGUN_WEAPON    3
#define HANDBOMB_WEAPON    4
#define RPG_WEAPON    5
#define SHRINKER_WEAPON    6
#define FREEZE_WEAPON    7
#define TRIPBOMB_WEAPON    8
#define DEVISTATOR_WEAPON    9
#define HANDREMOTE_WEAPON   10
#define GROW_WEAPON   11
#define BOWLING_WEAPON   12

// Defines the motion characteristics of an actor
#define faceplayer 1
#define geth 2
#define getv 4
#define randomangle 8
#define faceplayerslow 16
#define spin 32
#define faceplayersmart 64
#define fleeenemy 128
#define jumptoplayer 257
#define seekplayer 512
#define furthestdir 1024
#define dodgebullet 4096

// Some misc #defines
#define NO       0
#define YES      1

// Defines for 'useractor' keyword
#define notenemy       0
#define enemy          1
#define enemystayput   2

// Player Actions.
#define pstanding 1
#define pwalking 2
#define prunning 4
#define pducking 8
#define pfalling 16
#define pjumping 32
#define phigher 64
#define pwalkingback 128
#define prunningback 256
#define pkicking 512
#define pshrunk 1024
#define pjetpack 2048
#define ponsteroids 4096
#define ponground 8192
#define palive 16384
#define pdead 32768
#define pfacing 65536

#define GET_STEROIDS     0
#define GET_SHIELD       1
#define GET_SCUBA        2
#define GET_HOLODUKE     3
#define GET_JETPACK      4
#define GET_ACCESS       6
#define GET_HEATS        7
#define GET_FIRSTAID     9
#define GET_BOOTS       10

#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 SMACKIT                        394
#define BELLSND                        395
// MAXIMUM NUMBER OF SOUNDS: 450 ( 0-449 )


code:
//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
Copyright (C) 2017-2019 Nuke.YKT

This file is part of Duke Nukem 3D version 1.5 - Atomic Edition

Duke Nukem 3D is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

Original Source: 1996 - Todd Replogle
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------

#include <conio.h>
#include <stdio.h>
#include <string.h>
#include "types.h"
#include "sndcards.h"
#include "fx_man.h"
#include "music.h"
#include "util_lib.h"
#include "duke3d.h"

#define LOUDESTVOLUME 150

long backflag,numenvsnds;

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

void SoundStartup( void )
   {
   int32 status;

   // if they chose None lets return
   if (FXDevice == NumSoundCards) return;

   // Do special Sound Blaster, AWE32 stuff
   if (
         ( FXDevice == SoundBlaster ) ||
         ( FXDevice == Awe32 )
      )
      {
      int MaxVoices;
      int MaxBits;
      int MaxChannels;

      status = FX_SetupSoundBlaster
                  (
                  BlasterConfig, (int *)&MaxVoices, (int *)&MaxBits, (int *)&MaxChannels
                  );
      }
   else
      {
      status = FX_Ok;
      }

   if ( status == FX_Ok )
      {
      if ( eightytwofifty && numplayers > 1)
         {
         status = FX_Init( FXDevice, min( NumVoices,4 ), 1, 8, 8000 );
         }
      else
         {
         status = FX_Init( FXDevice, NumVoices, NumChannels, NumBits, MixRate );
         }
      if ( status == FX_Ok )
         {

         FX_SetVolume( FXVolume );
         if (ReverseStereo == 1)
            {
            FX_SetReverseStereo(!FX_GetReverseStereo());
            }
         }
      }
   if ( status != FX_Ok )
      {
      Error( FX_ErrorString( FX_Error ));
      }

   status = FX_SetCallBack( testcallback );

   if ( status != FX_Ok )
      {
      Error( FX_ErrorString( FX_Error ));
      }
   }

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

void SoundShutdown( void )
   {
   int32 status;

   // if they chose None lets return
   if (FXDevice == NumSoundCards)
      return;

   status = FX_Shutdown();
   if ( status != FX_Ok )
      {
      Error( FX_ErrorString( FX_Error ));
      }
   }

/*
===================
=
= MusicStartup
=
===================
*/

void MusicStartup( void )
   {
   int32 status;

   // if they chose None lets return
   if ((MusicDevice == NumSoundCards) || (eightytwofifty && numplayers > 1) )
      return;

   // satisfy AWE32 and WAVEBLASTER stuff
   BlasterConfig.Midi = MidiPort;

   // Do special Sound Blaster, AWE32 stuff
   if (
         ( FXDevice == SoundBlaster ) ||
         ( FXDevice == Awe32 )
      )
      {
      int MaxVoices;
      int MaxBits;
      int MaxChannels;

      FX_SetupSoundBlaster
                  (
                  BlasterConfig, (int *)&MaxVoices, (int *)&MaxBits, (int *)&MaxChannels
                  );
      }
   status = MUSIC_Init( MusicDevice, MidiPort );

   if ( status == MUSIC_Ok )
      {
      MUSIC_SetVolume( MusicVolume );
      }
   else
   {
       Error(MUSIC_ErrorString(MUSIC_ErrorCode));
   }
}

/*
===================
=
= MusicShutdown
=
===================
*/

void MusicShutdown( void )
   {
   int32 status;

   // if they chose None lets return
   if ((MusicDevice == NumSoundCards) || (eightytwofifty && numplayers > 1) )
      return;

   status = MUSIC_Shutdown();
   if ( status != MUSIC_Ok )
      {
      Error( MUSIC_ErrorString( MUSIC_ErrorCode ));
      }
   }

int USRHOOKS_GetMem(char **ptr, unsigned long size )
{
   *ptr = SafeMalloc(size);

   if (*ptr == NULL)
      return(USRHOOKS_Error);

   return( USRHOOKS_Ok);

}

int USRHOOKS_FreeMem(char *ptr)
{
   SafeFree(ptr);
   return( USRHOOKS_Ok);
}

char menunum=0;

void intomenusounds(void)
{
    short i;
    short menusnds[] =
    {
        390,
        390,
        390,
        390,
        390,
        390,
        390,
        390,
        390,
        390,
        390,
        390,
        390,
        390,
        390,
        390,
        390,
    };
    sound(menusnds[menunum++]);
    menunum %= 17;
}

void playmusic(char *fn)
{
    short      fp;
    long        l;
}

char loadsound(unsigned short num)
{
    long   fp, l;

    if(num >= NUM_SOUNDS || SoundToggle == 0) return 0;
    if (FXDevice == NumSoundCards) return 0;

    fp = kopen4load(sounds[num],loadfromgrouponly);
    if(fp == -1)
    {
        sprintf(&fta_quotes[113][0],"Sound %s(#%ld) not found.",sounds[num],num);
        FTA(113,&ps[myconnectindex]);
        return 0;
    }

    l = kfilelength( fp );
    soundsiz[num] = l;

    Sound[num].lock = 200;

    allocache((long *)&Sound[num].ptr,l,&Sound[num].lock);
    kread( fp, Sound[num].ptr , l);
    kclose( fp );
    return 1;
}

int xyzsound(short num,short i,long x,long y,long z)
{
    long sndist, cx, cy, cz, j,k;
    short pitche,pitchs,cs;
    int voice, sndang, ca, pitch;

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

    if( num >= NUM_SOUNDS ||
        FXDevice == NumSoundCards ||
        ( (soundm[num]&8) && ud.lockout ) ||
        SoundToggle == 0 ||
        Sound[num].num > 3 ||
        FX_VoiceAvailable(soundpr[num]) == 0 ||
        (ps[myconnectindex].timebeforeexit > 0 && ps[myconnectindex].timebeforeexit <= 26*3) ||
        ps[myconnectindex].gm&MODE_MENU) return -1;

    if( soundm[num]&4 )
    {
        if(VoiceToggle==0 || (ud.multimode > 1 && PN == APLAYER && sprite[i].yvel != screenpeek && ud.coop != 1) ) return -1;

        for(j=0;j<NUM_SOUNDS;j++)
          for(k=0;k<Sound[j].num;k++)
            if( (Sound[j].num > 0) && (soundm[j]&4) )
              return -1;
    }

    cx = ps[screenpeek].oposx;
    cy = ps[screenpeek].oposy;
    cz = ps[screenpeek].oposz;
    cs = ps[screenpeek].cursectnum;
    ca = ps[screenpeek].ang+ps[screenpeek].look_ang;

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

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

    pitchs = soundps[num];
    pitche = soundpe[num];
    cx = klabs(pitche-pitchs);

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

    sndist += soundvo[num];
    if( sndist && PN != MUSICANDSFX && !cansee(cx,cy,cz-(24<<8),cs,SX,SY,SZ-(24<<8),SECT) )
        sndist += sndist>>2;

    switch(num)
    {
        case PIPEBOMB_EXPLODE:
        case LASERTRIP_EXPLODE:
        case RPG_EXPLODE:
            if(sndist > (6144) )
                sndist = 6144;
            if(sector[ps[screenpeek].cursectnum].lotag == 2)
                pitch -= 1024;
            break;
        default:
            if(sector[ps[screenpeek].cursectnum].lotag == 2 && (soundm[num]&4) == 0)
                pitch = -768;
            if( sndist > 31444 && PN != MUSICANDSFX)
                return -1;
            break;
    }

    if( Sound[num].num > 0 && PN != MUSICANDSFX )
    {
        if( SoundOwner[num][0].i == i ) stopsound(num);
        else if( Sound[num].num > 1 ) stopsound(num);
        else if( badguy(&sprite[i]) && sprite[i].extra <= 0 ) stopsound(num);
    }

    if( PN == APLAYER && sprite[i].yvel == screenpeek )
    {
        sndang = 0;
        sndist = 0;
    }
    else
    {
        sndang = 2048 + ca - getangle(cx-x,cy-y);
        sndang &= 2047;
    }

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

    if( soundm[num]&16 ) sndist = 0;

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

    if( soundm[num]&1 )
    {
        unsigned short start;

        if(Sound[num].num > 0) return -1;

        start = *(unsigned short *)(Sound[num].ptr + 0x14);

        if(*Sound[num].ptr == 'C')
            voice = FX_PlayLoopedVOC( Sound[num].ptr, start, start + soundsiz[num],
                    pitch,sndist>>6,sndist>>6,0,soundpr[num],num);
        else
            voice = FX_PlayLoopedWAV( Sound[num].ptr, start, start + soundsiz[num],
                    pitch,sndist>>6,sndist>>6,0,soundpr[num],num);
    }
    else
    {
        if( *Sound[num].ptr == 'C')
            voice = FX_PlayVOC3D( Sound[ num ].ptr,pitch,sndang>>6,sndist>>6, soundpr[num], num );
        else voice = FX_PlayWAV3D( Sound[ num ].ptr,pitch,sndang>>6,sndist>>6, soundpr[num], num );
    }

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

void sound(short num)
{
    short pitch,pitche,pitchs,cx;
    int voice;
    long start;

    if (FXDevice == NumSoundCards) return;
    if(SoundToggle==0) return;
    if(VoiceToggle==0 && (soundm[num]&4) ) return;
    if( (soundm[num]&8) && ud.lockout ) return;
    if(FX_VoiceAvailable(soundpr[num]) == 0) return;

    pitchs = soundps[num];
    pitche = soundpe[num];
    cx = klabs(pitche-pitchs);

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

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

    if( soundm[num]&1 )
    {
        if(*Sound[num].ptr == 'C')
        {
            start = (long)*(unsigned short *)(Sound[num].ptr + 0x14);
            voice = FX_PlayLoopedVOC( Sound[num].ptr, start, start + soundsiz[num],
                    pitch,LOUDESTVOLUME,LOUDESTVOLUME,LOUDESTVOLUME,soundpr[num],num);
        }
        else
        {
            start = (long)*(unsigned short *)(Sound[num].ptr + 0x14);
            voice = FX_PlayLoopedWAV( Sound[num].ptr, start, start + soundsiz[num],
                    pitch,LOUDESTVOLUME,LOUDESTVOLUME,LOUDESTVOLUME,soundpr[num],num);
        }
    }
    else
    {
        if(*Sound[num].ptr == 'C')
            voice = FX_PlayVOC3D( Sound[ num ].ptr, pitch,0,255-LOUDESTVOLUME,soundpr[num], num );
        else
            voice = FX_PlayWAV3D( Sound[ num ].ptr, pitch,0,255-LOUDESTVOLUME,soundpr[num], num );
    }

    if(voice > FX_Ok) return;
    Sound[num].lock--;
}

int spritesound(unsigned short num, short i)
{
    if(num >= NUM_SOUNDS) return -1;
    return xyzsound(num,i,SX,SY,SZ);
}

void stopsound(short num)
{
    if(Sound[num].num > 0)
    {
        FX_StopSound(SoundOwner[num][Sound[num].num-1].voice);
        testcallback(num);
    }
}

void stopenvsound(short num,short i)
{
    short j, k;

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

void pan3dsound(void)
{
    long sndist, sx, sy, sz, cx, cy, cz;
    short sndang,ca,j,k,i,cs;

    numenvsnds = 0;

    if(ud.camerasprite == -1)
    {
        cx = ps[screenpeek].oposx;
        cy = ps[screenpeek].oposy;
        cz = ps[screenpeek].oposz;
        cs = ps[screenpeek].cursectnum;
        ca = ps[screenpeek].ang+ps[screenpeek].look_ang;
    }
    else
    {
        cx = sprite[ud.camerasprite].x;
        cy = sprite[ud.camerasprite].y;
        cz = sprite[ud.camerasprite].z;
        cs = sprite[ud.camerasprite].sectnum;
        ca = sprite[ud.camerasprite].ang;
    }

    for(j=0;j<NUM_SOUNDS;j++) for(k=0;k<Sound[j].num;k++)
    {
        i = SoundOwner[j][k].i;

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

        if( PN == APLAYER && sprite[i].yvel == screenpeek)
        {
            sndang = 0;
            sndist = 0;
        }
        else
        {
            sndang = 2048 + ca - getangle(cx-sx,cy-sy);
            sndang &= 2047;
            sndist = FindDistance3D((cx-sx),(cy-sy),(cz-sz)>>4);
            if( i >= 0 && (soundm[j]&16) == 0 && PN == MUSICANDSFX && SLT < 999 && (sector[SECT].lotag&0xff) < 9 )
                sndist = divscale14(sndist,(SHT+1));
        }

        sndist += soundvo[j];

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

        if(PN == MUSICANDSFX && SLT < 999)
            numenvsnds++;

        switch(j)
        {
            case PIPEBOMB_EXPLODE:
            case LASERTRIP_EXPLODE:
            case RPG_EXPLODE:
                if(sndist > (6144)) sndist = (6144);
                break;
            default:
                if( sndist > 31444 && PN != MUSICANDSFX)
                {
                    stopsound(j);
                    continue;
                }
        }

        if(Sound[j].ptr == 0 && loadsound(j) == 0 ) continue;
        if( soundm[j]&16 ) sndist = 0;

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

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

void testcallback(long num)
{
    int tempi,tempj,tempk;

        if(num < 0)
        {
            if(lumplockbyte[-num] >= 200)
                lumplockbyte[-num]--;
            return;
        }

        if(Sound[num].num > 0)
        {
            tempk = Sound[num].num;

            if( (soundm[num]&16) == 0)
                for(tempj=0;tempj<tempk;tempj++)
            {
                tempi = SoundOwner[num][tempj].i;
                if(sprite[tempi].picnum == MUSICANDSFX && sector[sprite[tempi].sectnum].lotag < 3 && sprite[tempi].lotag < 999)
                {
                    hittype[tempi].temp_data[0] = 0;
                    if( (tempj + 1) < tempk )
                    {
                        SoundOwner[num][tempj].voice = SoundOwner[num][tempk-1].voice;
                        SoundOwner[num][tempj].i     = SoundOwner[num][tempk-1].i;
                    }
                    break;
                }
            }

            Sound[num].num--;
            SoundOwner[num][tempk-1].i = -1;
        }

        Sound[num].lock--;
}

void clearsoundlocks(void)
{
    long i;

    for(i=0;i<NUM_SOUNDS;i++)
        if(Sound[i].lock >= 200)
            Sound[i].lock = 199;

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

repo_name: orochi/nblood

license: mit


code:
//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
Copyright (C) 2017-2019 Nuke.YKT

This file is part of Duke Nukem 3D version 1.5 - Atomic Edition

Duke Nukem 3D is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

Original Source: 1996 - Todd Replogle
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------

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

#ifndef _sounds_public_
#define _sounds_public_

extern int32 FXDevice;
extern int32 MusicDevice;
extern int32 FXVolume;
extern int32 MusicVolume;
extern fx_blaster_config BlasterConfig;
extern int32 NumVoices;
extern int32 NumChannels;
extern int32 NumBits;
extern int32 MixRate;
extern int32 MidiPort;
extern int32 ReverseStereo;

void SoundStartup( void );
void SoundShutdown( void );
void MusicStartup( void );
void MusicShutdown( void );

#endif


code:
//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
Copyright (C) 2017-2019 Nuke.YKT

This file is part of Duke Nukem 3D version 1.5 - Atomic Edition

Duke Nukem 3D is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

Original Source: 1994 - Jim Dose
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------

#ifndef __TASK_MAN_H
#define __TASK_MAN_H

enum TASK_ERRORS
   {
   TASK_Warning = -2,
   TASK_Error = -1,
   TASK_Ok = 0
   };

typedef struct task
{
    struct   task *next;
    struct   task *prev;
    void          ( *TaskService )( struct task * );
    void          *data;
    long          rate;
    volatile long count;
    int           priority;
    int           active;
} task;

// TS_InInterrupt is TRUE during a taskman interrupt.
// Use this if you have code that may be used both outside
// and within interrupts.

extern volatile int TS_InInterrupt;

void    TS_Shutdown( void );
task    *TS_ScheduleTask( void ( *Function )( task * ), int rate,
                          int priority, void *data );
int     TS_Terminate( task *ptr );
void    TS_Dispatch( void );
void    TS_SetTaskRate( task *Task, int rate );
void    TS_UnlockMemory( void );
int     TS_LockMemory( void );

#endif


code:
//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
Copyright (C) 2017-2019 Nuke.YKT

This file is part of Duke Nukem 3D version 1.5 - Atomic Edition

Duke Nukem 3D is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

Original Source: 1996 - Todd Replogle
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------

#ifndef _types_public
#define _types_public
#ifdef __cplusplus
extern "C" {
#endif

//***************************************************************************
//
//  Global Data Types (For portability)
//
//***************************************************************************

typedef unsigned char           uint8;
typedef uint8                   byte;
typedef signed char             int8;

typedef unsigned short int      uint16;
typedef uint16                  word;
typedef short int               int16;

typedef unsigned long           uint32;
typedef long                    int32;
typedef uint32                  dword;

typedef int32                   fixed;
typedef int32                   boolean;
typedef float                   float32;
typedef double                  float64;
typedef long double             float128;
typedef float64                 appfloat;

#define MAXINT32                0x7fffffff
#define MININT32                -0x80000000
#define MAXUINT32               0xffffffff
#define MINUINT32               0

#define MAXINT16                0x7fff
#define MININT16                -0x8000
#define MAXUINT16               0xffff
#define MINUINT16               0

//***************************************************************************
//
//  boolean values
//
//***************************************************************************

#define true ( 1 == 1 )
#define false ( ! true )

//***************************************************************************
//
//  BYTE ACCESS MACROS
//
//***************************************************************************

// WORD macros
#define Int16_HighByte( x ) ( (uint8) ((x)>>8) )
#define Int16_LowByte( x )  ( (uint8) ((x)&0xff) )

// DWORD macros
#define Int32_4Byte( x )   ( (uint8) ((x)>>24)&0xff )
#define Int32_3Byte( x )   ( (uint8) (((x)>>16)&0xff) )
#define Int32_2Byte( x )   ( (uint8) (((x)>>8)&0xff) )
#define Int32_1Byte( x )   ( (uint8) ((x)&0xff) )

#ifdef __NeXT__
#define stricmp strcasecmp
#define strcmpi strcasecmp
#endif

#ifdef __cplusplus
};
#endif
#endif


code:
//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
Copyright (C) 2017-2019 Nuke.YKT

This file is part of Duke Nukem 3D version 1.5 - Atomic Edition

Duke Nukem 3D is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

Original Source: 1996 - Todd Replogle
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------

//***************************************************************************
//
//    UTIL_LIB.C - various utils
//
//***************************************************************************

#ifndef _util_lib_public
#define _util_lib_public
#ifdef __cplusplus
extern "C" {
#endif

#if (defined(__MSDOS__) && !defined(__FLAT__))
extern  int16    _argc;
#else
extern  int32    _argc;
#endif
extern  char **  _argv;

void RegisterShutdownFunction( void (* shutdown) (void) );
void   Error (char *error, ...);

char   CheckParm (char *check);

void   *SafeMalloc (int32 size);
int32  SafeMallocSize (void * ptr);
void   SafeFree (void * ptr);
void   SafeRealloc (void ** ptr, int32 newsize);
int32  ParseHex (char *hex);
int32  ParseNum (char *str);
int16  MotoShort (int16 l);
int16  IntelShort (int16 l);
int32  MotoLong (int32 l);
int32  IntelLong (int32 l);

void HeapSort(char * base, int32 nel, int32 width, int32 (*compare)(), void (*switcher)());

#ifdef __cplusplus
};
#endif
#endif


code:
//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
Copyright (C) 2017-2019 Nuke.YKT

This file is part of Duke Nukem 3D version 1.5 - Atomic Edition

Duke Nukem 3D is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

Original Source: 1996 - Todd Replogle
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------

/////////////////////////////////////////////////////////////////////////////
//
//      ANIMLIB.H
//
/////////////////////////////////////////////////////////////////////////////

#ifndef _animlib_private_
#define _animlib_private_
#ifdef __cplusplus
extern "C" {
#endif

#ifdef __cplusplus
};
#endif
#endif


code:
//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
Copyright (C) 2017-2019 Nuke.YKT

This file is part of Duke Nukem 3D version 1.5 - Atomic Edition

Duke Nukem 3D is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

Original Source: 1996 - Todd Replogle
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------

// _functio.h

// file created by makehead.exe
// these headers contain default key assignments, as well as
// default button assignments and game function names
// axis defaults are also included

#ifndef _function_private_
#define _function_private_
#ifdef __cplusplus
extern "C" {
#endif
char * gamefunctions[] =
   {
   "Move_Forward",
   "Move_Backward",
   "Turn_Left",
   "Turn_Right",
   "Strafe",
   "Fire",
   "Open",
   "Run",
   "AutoRun",
   "Jump",
   "Crouch",
   "Look_Up",
   "Look_Down",
   "Look_Left",
   "Look_Right",
   "Strafe_Left",
   "Strafe_Right",
   "Aim_Up",
   "Aim_Down",
   "Weapon_1",
   "Weapon_2",
   "Weapon_3",
   "Weapon_4",
   "Weapon_5",
   "Weapon_6",
   "Weapon_7",
   "Weapon_8",
   "Weapon_9",
   "Weapon_10",
   "Inventory",
   "Inventory_Left",
   "Inventory_Right",
   "Beer",
   "CowPie",
   "Yeehaa",
   "Whiskey",
   "TurnAround",
   "SendMessage",
   "Map",
   "Shrink_Screen",
   "Enlarge_Screen",
   "Center_View",
   "Holster_Weapon",
   "Show_Opponents_Weapon",
   "Map_Follow_Mode",
   "See_Coop_View",
   "Mouse_Aiming",
   "Toggle_Crosshair",
   "Moonshine",
   "LockView",
   "Next_Weapon",
   "Previous_Weapon",
   };
#ifdef __SETUP__

#define NUMKEYENTRIES 52

static char * keydefaults[] =
   {
   "Move_Forward", "Up", "Kpad8",
   "Move_Backward", "Down", "Kpad2",
   "Turn_Left", "Left", "Kpad4",
   "Turn_Right", "Right", "KPad6",
   "Strafe", "LAlt", "RAlt",
   "Fire", "LCtrl", "RCtrl",
   "Open", "Space", "",
   "Run", "LShift", "RShift",
   "AutoRun", "CapLck", "",
   "Jump", "A", "/",
   "Crouch", "Z", "",
   "Look_Up", "PgUp", "Kpad9",
   "Look_Down", "PgDn", "Kpad3",
   "Look_Left", "Insert", "Kpad0",
   "Look_Right", "Delete", "Kpad.",
   "Strafe_Left", ",", "",
   "Strafe_Right", ".", "",
   "Aim_Up", "Home", "KPad7",
   "Aim_Down", "End", "Kpad1",
   "Weapon_1", "1", "",
   "Weapon_2", "2", "",
   "Weapon_3", "3", "",
   "Weapon_4", "4", "",
   "Weapon_5", "5", "",
   "Weapon_6", "6", "",
   "Weapon_7", "7", "",
   "Weapon_8", "8", "",
   "Weapon_9", "9", "",
   "Weapon_10", "0", "",
   "Inventory", "Enter", "KpdEnt",
   "Inventory_Left", "[", "",
   "Inventory_Right", "]", "",
   "Holo_Duke", "H", "",
   "Jetpack", "J", "",
   "NightVision", "N", "",
   "MedKit", "M", "",
   "TurnAround", "BakSpc", "",
   "SendMessage", "T", "",
   "Map", "Tab", "",
   "Shrink_Screen", "-", "Kpad-",
   "Enlarge_Screen", "=", "Kpad+",
   "Center_View", "KPad5", "",
   "Holster_Weapon", "ScrLck", "",
   "Show_Opponents_Weapon", "W", "",
   "Map_Follow_Mode", "F", "",
   "See_Coop_View", "K", "",
   "Mouse_Aiming", "U", "",
   "Toggle_Crosshair", "I", "",
   "Steroids", "R", "",
   "Quick_Kick", "`", "",
   "Next_Weapon", "'", "",
   "Previous_Weapon", ";", "",
   };

static char * mousedefaults[] =
   {
   "Fire",
   "Strafe",
   "Move_Forward",
   };

static char * mouseclickeddefaults[] =
   {
   "",
   "Open",
   "",
   };

static char * joystickdefaults[] =
   {
   "Fire",
   "Strafe",
   "Run",
   "Open",
   "Aim_Down",
   "Look_Right",
   "Aim_Up",
   "Look_Left",
   };

static char * joystickclickeddefaults[] =
   {
   "",
   "Inventory",
   "Jump",
   "Crouch",
   "",
   "",
   "",
   "",
   };

static char * mouseanalogdefaults[] =
   {
   "analog_turning",
   "analog_moving",
   };

static char * mousedigitaldefaults[] =
   {
   "",
   "",
   "",
   "",
   };

static char * gamepaddigitaldefaults[] =
   {
   "Turn_Left",
   "Turn_Right",
   "Move_Forward",
   "Move_Backward",
   };

static char * joystickanalogdefaults[] =
   {
   "analog_turning",
   "analog_moving",
   "analog_strafing",
   "",
   };

static char * joystickdigitaldefaults[] =
   {
   "",
   "",
   "",
   "",
   "",
   "",
   "Run",
   "",
   };
#endif
#ifdef __cplusplus
};
#endif
#endif


code:
//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
Copyright (C) 2017-2019 Nuke.YKT

This file is part of Duke Nukem 3D version 1.5 - Atomic Edition

Duke Nukem 3D is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

Original Source: 1996 - Todd Replogle
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------

#ifndef __rts_private__
#define __rts_private__

//===============
//   TYPES
//===============

typedef struct
   {
   char name[8];
   int32 handle,position,size;
   } lumpinfo_t;

typedef struct
   {
   char identification[4];              // should be IWAD
   int32 numlumps;
   int32 infotableofs;
   } wadinfo_t;

typedef struct
   {
   int32 filepos;
   int32 size;
   char name[8];
   } filelump_t;

#endif


code:
//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
Copyright (C) 2017-2019 Nuke.YKT

This file is part of Duke Nukem 3D version 1.5 - Atomic Edition

Duke Nukem 3D is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

Original Source: 1996 - Todd Replogle
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------

#include "duke3d.h"

extern char actor_tog;

void updateinterpolations()  //Stick at beginning of domovethings
{
	long i;

	for(i=numinterpolations-1;i>=0;i--) oldipos[i] = *curipos[i];
}

void setinterpolation(long *posptr)
{
	long i;

	if (numinterpolations >= MAXINTERPOLATIONS) return;
	for(i=numinterpolations-1;i>=0;i--)
		if (curipos[i] == posptr) return;
	curipos[numinterpolations] = posptr;
	oldipos[numinterpolations] = *posptr;
	numinterpolations++;
}

void stopinterpolation(long *posptr)
{
	long i;

	for(i=numinterpolations-1;i>=startofdynamicinterpolations;i--)
		if (curipos[i] == posptr)
		{
			numinterpolations--;
			oldipos[i] = oldipos[numinterpolations];
			bakipos[i] = bakipos[numinterpolations];
			curipos[i] = curipos[numinterpolations];
		}
}

void dointerpolations(long smoothratio)       //Stick at beginning of drawscreen
{
	long i, j, odelta, ndelta;

	ndelta = 0; j = 0;
	for(i=numinterpolations-1;i>=0;i--)
	{
		bakipos[i] = *curipos[i];
		odelta = ndelta; ndelta = (*curipos[i])-oldipos[i];
		if (odelta != ndelta) j = mulscale16(ndelta,smoothratio);
		*curipos[i] = oldipos[i]+j;
	}
}

void restoreinterpolations()  //Stick at end of drawscreen
{
	long i;

	for(i=numinterpolations-1;i>=0;i--) *curipos[i] = bakipos[i];
}

long ceilingspace(short sectnum)
{
    if( (sector[sectnum].ceilingstat&1) && sector[sectnum].ceilingpal == 0 )
    {
        switch(sector[sectnum].ceilingpicnum)
        {
            case MOONSKY1:
            case BIGORBIT1:
                return 1;
        }
    }
    return 0;
}

long floorspace(short sectnum)
{
    if( (sector[sectnum].floorstat&1) && sector[sectnum].ceilingpal == 0 )
    {
        switch(sector[sectnum].floorpicnum)
        {
            case MOONSKY1:
            case BIGORBIT1:
                return 1;
        }
    }
    return 0;
}

void addammo( short weapon,struct player_struct *p,short amount)
{
   p->ammo_amount[weapon] += amount;

   if( p->ammo_amount[weapon] > max_ammo_amount[weapon] )
        p->ammo_amount[weapon] = max_ammo_amount[weapon];

   if (ud.screen_size > 8)
       weaponbar(screenpeek);
}

void addweapon( struct player_struct *p,short weapon)
{
    short cw = p->curr_weapon;
#ifdef RRRA
    if (p->OnMotorcycle || p->OnBoat)
    {
        p->gotweapon[weapon] = 1;
        if (weapon == SHRINKER_WEAPON)
        {
            p->gotweapon[GROW_WEAPON] = 1;
            p->gotweapon[SHRINKER_WEAPON] = 1;
            p->ammo_amount[GROW_WEAPON] = 1;
        }
        else if (weapon == RPG_WEAPON)
        {
            p->gotweapon[RPG_WEAPON] = 1;
            p->gotweapon[RA16_WEAPON] = 1;
        }
        else if (weapon == RA15_WEAPON)
        {
            p->gotweapon[RA15_WEAPON] = 1;
            p->ammo_amount[RA15_WEAPON] = 1;
        }
        return;
    }
#endif
    if ( p->gotweapon[weapon] == 0 )
    {
        p->gotweapon[weapon] = 1;
        if (weapon == SHRINKER_WEAPON)
        {
            p->gotweapon[GROW_WEAPON] = 1;
            p->gotweapon[SHRINKER_WEAPON] = 1;
            p->ammo_amount[GROW_WEAPON] = 1;
        }
#ifdef RRRA
        else if (weapon == RPG_WEAPON)
        {
            p->gotweapon[RPG_WEAPON] = 1;
            p->gotweapon[RA16_WEAPON] = 1;
        }
        else if (weapon == RA15_WEAPON)
        {
            p->gotweapon[RA15_WEAPON] = 1;
            p->ammo_amount[RA15_WEAPON] = 50;
        }
#endif
        if (weapon != HANDBOMB_WEAPON)
            cw = weapon;
    }
    else
        cw = weapon;

    if (weapon == HANDBOMB_WEAPON)
        p->last_weapon = -1;

    p->random_club_frame = 0;

    if(p->holster_weapon == 0)
    {
        p->weapon_pos = -1;
        p->last_weapon = p->curr_weapon;
    }
    else
    {
        p->weapon_pos = 10;
        p->holster_weapon = 0;
        p->last_weapon = -1;
    }

    p->kickback_pic = 0;
    p->curr_weapon = cw;

    switch(weapon)
    {
#ifdef RRRA
        case RA15_WEAPON:
#endif
        case KNEE_WEAPON:
        case HANDBOMB_WEAPON:
        case TRIPBOMB_WEAPON:
        case HANDREMOTE_WEAPON:   break;
        case SHOTGUN_WEAPON:      spritesound(SHOTGUN_COCK,p->i);break;
        case PISTOL_WEAPON:       spritesound(INSERT_CLIP,p->i);break;
                    default:      spritesound(EJECT_CLIP,p->i);break;
    }
}

void checkavailinven( struct player_struct *p )
{

    if(p->firstaid_amount > 0)
        p->inven_icon = 1;
    else if(p->steroids_amount > 0)
        p->inven_icon = 2;
    else if(p->holoduke_amount > 0)
        p->inven_icon = 3;
    else if(p->jetpack_amount > 0)
        p->inven_icon = 4;
    else if(p->heat_amount > 0)
        p->inven_icon = 5;
    else if(p->scuba_amount > 0)
        p->inven_icon = 6;
    else if(p->boot_amount > 0)
        p->inven_icon = 7;
    else p->inven_icon = 0;
}

void checkavailweapon( struct player_struct *p )
{
    short i,snum;
    int32 weap;

    if(p->wantweaponfire >= 0)
    {
        weap = p->wantweaponfire;
        p->wantweaponfire = -1;

        if(weap == p->curr_weapon) return;
        else if( p->gotweapon[weap] && p->ammo_amount[weap] > 0 )
        {
            addweapon(p,weap);
            return;
        }
    }

    weap = p->curr_weapon;
    if( p->gotweapon[weap] && p->ammo_amount[weap] > 0 )
        return;

    snum = sprite[p->i].yvel;

    for(i=0;i<10;i++)
    {
        weap = ud.wchoice[snum][i];

        if(weap == 0) weap = 9;
        else weap--;

        if( weap == 0 || ( p->gotweapon[weap] && p->ammo_amount[weap] > 0 ) )
            break;
    }

    if(i == 10) weap = 0;

    // Found the weapon

    p->last_weapon  = p->curr_weapon;
    p->random_club_frame = 0;
    p->curr_weapon  = weap;
    p->kickback_pic = 0;
    if(p->holster_weapon == 1)
    {
        p->holster_weapon = 0;
        p->weapon_pos = 10;
    }
    else p->weapon_pos   = -1;
}

 /*
void checkavailweapon( struct player_struct *p )
{
    short i,okay,check_shoot,check_bombs;

    if(p->ammo_amount[p->curr_weapon] > 0) return;
    okay = check_shoot = check_bombs = 0;

    switch(p->curr_weapon)
    {
        case PISTOL_WEAPON:
        case CHAINGUN_WEAPON:
        case SHOTGUN_WEAPON:
#ifndef VOLUMEONE
        case FREEZE_WEAPON:
        case DEVISTATOR_WEAPON:
        case SHRINKER_WEAPON:
        case GROW_WEAPON:
#endif
        case RPG_WEAPON:
        case KNEE_WEAPON:
            check_shoot = 1;
            break;
        case HANDBOMB_WEAPON:
        case HANDREMOTE_WEAPON:
#ifndef VOLUMEONE
        case TRIPBOMB_WEAPON:
#endif
            check_bombs = 1;
            break;
    }

    CHECK_SHOOT:
    if(check_shoot)
    {
        for(i = p->curr_weapon+1; i < MAX_WEAPONS;i++)
            switch(i)
            {
                case PISTOL_WEAPON:
                case CHAINGUN_WEAPON:
                case SHOTGUN_WEAPON:
#ifndef VOLUMEONE
                case FREEZE_WEAPON:
                case SHRINKER_WEAPON:
                case GROW_WEAPON:
                case DEVISTATOR_WEAPON:
#endif
                    if ( p->gotweapon[i] && p->ammo_amount[i] > 0 )
                    {
                        okay = i;
                        goto OKAY_HERE;
                    }
                    break;
            }

        for(i = p->curr_weapon-1; i > 0;i--)
            switch(i)
            {
                case PISTOL_WEAPON:
                case CHAINGUN_WEAPON:
                case SHOTGUN_WEAPON:
#ifndef VOLUMEONE
                case FREEZE_WEAPON:
                case DEVISTATOR_WEAPON:
                case SHRINKER_WEAPON:
                case GROW_WEAPON:
#endif
                    if ( p->gotweapon[i] && p->ammo_amount[i] > 0 )
                    {
                        okay = i;
                        goto OKAY_HERE;
                    }
                    break;
            }

        if( p->gotweapon[RPG_WEAPON] && p->ammo_amount[RPG_WEAPON] > 0 )
        {
            okay = RPG_WEAPON;
            goto OKAY_HERE;
        }

        if(check_bombs == 0)
            check_bombs = 1;
        else
        {
            addweapon(p,KNEE_WEAPON);
            return;
        }
    }

    if(check_bombs)
    {
        for(i = p->curr_weapon-1; i > 0;i--)
            switch(i)
            {
                case HANDBOMB_WEAPON:
#ifndef VOLUMEONE
                case TRIPBOMB_WEAPON:
#endif
                    if ( p->gotweapon[i] && p->ammo_amount[i] > 0 )
                    {
                        okay = i;
                        goto OKAY_HERE;
                    }
                    break;
            }

        for(i = p->curr_weapon+1; i < MAX_WEAPONS;i++)
            switch(i)
            {
                case HANDBOMB_WEAPON:
#ifdef VOLUMEONE
                case TRIPBOMB_WEAPON:
#endif
                    if ( p->gotweapon[i] && p->ammo_amount[i] > 0 )
                    {
                        okay = i;
                        goto OKAY_HERE;
                    }
                    break;
            }

        if(check_shoot == 0)
        {
            check_shoot = 1;
            goto CHECK_SHOOT;
        }
        else
        {
            addweapon(p,KNEE_WEAPON);
            return;
        }
    }

    OKAY_HERE:

    if(okay)
    {
        p->last_weapon  = p->curr_weapon;
        p->random_club_frame = 0;
        p->curr_weapon  = okay;
        p->kickback_pic = 0;
        if(p->holster_weapon == 1)
        {
            p->holster_weapon = 0;
            p->weapon_pos = 10;
        }
        else p->weapon_pos   = -1;
        return;
    }
}
   */

long ifsquished(short i, short p)
{
    return 0;
}

void hitradius( short i, long  r, long  hp1, long  hp2, long  hp3, long  hp4 )
{
    spritetype *s,*sj;
    walltype *wal;
    long d, q, x1, y1;
    long sectcnt, sectend, dasect, startwall, endwall, nextsect;
    short j,k,p,x,nextj,sect;
    char statlist[] = {0,1,6,10,12,2,5};
    short *tempshort = (short *)tempbuf;

    s = &sprite[i];

    if(s->picnum == RPG && s->xrepeat < 11) goto SKIPWALLCHECK;
#ifdef RRRA
    if(s->picnum == RPG2 && s->xrepeat < 11) goto SKIPWALLCHECK;
#endif

    tempshort[0] = s->sectnum;
    dasect = s->sectnum;
    sectcnt = 0; sectend = 1;

    do
    {
        dasect = tempshort[sectcnt++];
        if(((sector[dasect].ceilingz-s->z)>>8) < r)
        {
            d = klabs(wall[sector[dasect].wallptr].x-s->x)+klabs(wall[sector[dasect].wallptr].y-s->y);
            if(d < r)
                checkhitceiling(dasect);
            else
            {
                d = klabs(wall[wall[wall[sector[dasect].wallptr].point2].point2].x-s->x)+klabs(wall[wall[wall[sector[dasect].wallptr].point2].point2].y-s->y);
                if(d < r)
                    checkhitceiling(dasect);
            }
        }

        startwall = sector[dasect].wallptr;
        endwall = startwall+sector[dasect].wallnum;
        for(x=startwall,wal=&wall[startwall];x<endwall;x++,wal++)
            if( ( klabs(wal->x-s->x)+klabs(wal->y-s->y) ) < r)
        {
            nextsect = wal->nextsector;
            if (nextsect >= 0)
            {
                for(dasect=sectend-1;dasect>=0;dasect--)
                    if (tempshort[dasect] == nextsect) break;
                if (dasect < 0) tempshort[sectend++] = nextsect;
            }
            x1 = (((wal->x+wall[wal->point2].x)>>1)+s->x)>>1;
            y1 = (((wal->y+wall[wal->point2].y)>>1)+s->y)>>1;
            updatesector(x1,y1,&sect);
            if( sect >= 0 && cansee(x1,y1,s->z,sect,s->x,s->y,s->z,s->sectnum ) )
                checkhitwall(i,x,wal->x,wal->y,s->z,s->picnum);
        }
    }
    while (sectcnt < sectend);

    SKIPWALLCHECK:

    q = -(24<<8)+(TRAND&((32<<8)-1));

    for(x = 0;x<7;x++)
    {
        j = headspritestat[statlist[x]];
        while(j >= 0)
        {
            nextj = nextspritestat[j];
            sj = &sprite[j];

            if( x == 0 || x >= 5 || AFLAMABLE(sj->picnum) )
            {
                if( sj->cstat&257 )
                    if( dist( s, sj ) < r )
                    {
                        if( badguy(sj) && !cansee( sj->x, sj->y,sj->z+q, sj->sectnum, s->x, s->y, s->z+q, s->sectnum) )
                            goto BOLT;
                        checkhitsprite( j, i );
                    }
            }
            else if( sj->extra >= 0 && sj != s && ( badguy(sj) || sj->picnum == QUEBALL || sj->picnum == RRTILE3440 || sj->picnum == STRIPEBALL || (sj->cstat&257) || sj->picnum == DUKELYINGDEAD ) )
            {
                if( s->picnum == MORTER && j == s->owner)
                {
                    j = nextj;
                    continue;
                }
#ifdef RRRA
                if( s->picnum == CHEERBOMB && j == s->owner)
                {
                    j = nextj;
                    continue;
                }
#endif

                if(sj->picnum == APLAYER) sj->z -= PHEIGHT;
                d = dist( s, sj );
                if(sj->picnum == APLAYER) sj->z += PHEIGHT;

                if ( d < r && cansee( sj->x, sj->y, sj->z-(8<<8), sj->sectnum, s->x, s->y, s->z-(12<<8), s->sectnum) )
                {
#ifdef RRRA
                    if (sprite[j].picnum == MINION && sprite[j].pal == 19)
                    {
                        j = nextj;
                        continue;
                    }

#endif
                    hittype[j].ang = getangle(sj->x-s->x,sj->y-s->y);

                    if ( s->picnum == RPG && sj->extra > 0)
                        hittype[j].picnum = RPG;
#ifdef RRRA
                    else if (s->picnum == RPG2 && sj->extra > 0)
                        hittype[j].picnum = RPG;
#endif
                    else
                        hittype[j].picnum = RADIUSEXPLOSION;

                    if ( d < r/3 )
                    {
                        if(hp4 == hp3) hp4++;
                        hittype[j].extra = hp3 + (TRAND%(hp4-hp3));
                    }
                    else if ( d < 2*r/3 )
                    {
                        if(hp3 == hp2) hp3++;
                        hittype[j].extra = hp2 + (TRAND%(hp3-hp2));
                    }
                    else if ( d < r )
                    {
                        if(hp2 == hp1) hp2++;
                        hittype[j].extra = hp1 + (TRAND%(hp2-hp1));
                    }

#ifdef RRRA
                    if( sprite[j].picnum != HULK && sprite[j].picnum != MAMA && sprite[j].picnum != BILLYPLAY && sprite[j].picnum != COOTPLAY && sprite[j].picnum != MAMACLOUD )
#else
                    if( sprite[j].picnum != HULK && sprite[j].picnum != SBMOVE)
#endif
                    {
                        if(sprite[j].xvel < 0) sprite[j].xvel = 0;
                        sprite[j].xvel += (sprite[j].extra<<2);
                    }

                    if( sj->picnum == STATUEFLASH || sj->picnum == QUEBALL ||
                        sj->picnum == STRIPEBALL || sj->picnum == RRTILE3440 )
                            checkhitsprite( j, i );

                    if ( sprite[j].picnum != RADIUSEXPLOSION &&
                        s->owner >= 0 && sprite[s->owner].statnum < MAXSTATUS )
                    {
                        if(sprite[j].picnum == APLAYER)
                        {
                            p = sprite[j].yvel;
                            if(ps[p].newowner >= 0)
                            {
                                ps[p].newowner = -1;
                                ps[p].posx = ps[p].oposx;
                                ps[p].posy = ps[p].oposy;
                                ps[p].posz = ps[p].oposz;
                                ps[p].ang = ps[p].oang;
                                updatesector(ps[p].posx,ps[p].posy,&ps[p].cursectnum);
                                setpal(&ps[p]);

                                k = headspritestat[1];
                                while(k >= 0)
                                {
                                    if(sprite[k].picnum==CAMERA1)
                                        sprite[k].yvel = 0;
                                    k = nextspritestat[k];
                                }
                            }
                        }
                        hittype[j].owner = s->owner;
                    }
                }
            }
            BOLT:
            j = nextj;
        }
    }
}

movesprite(short spritenum, long xchange, long ychange, long zchange, unsigned long cliptype)
{
    long daz,h, oldx, oldy;
    short retval, dasectnum, a, cd;
    char bg;

    bg = badguy(&sprite[spritenum]);

    if(sprite[spritenum].statnum == 5 || (bg && sprite[spritenum].xrepeat < 4 ) )
    {
        sprite[spritenum].x += (xchange*TICSPERFRAME)>>2;
        sprite[spritenum].y += (ychange*TICSPERFRAME)>>2;
        sprite[spritenum].z += (zchange*TICSPERFRAME)>>2;
        if(bg)
            setsprite(spritenum,sprite[spritenum].x,sprite[spritenum].y,sprite[spritenum].z);
        return 0;
    }

    dasectnum = sprite[spritenum].sectnum;

	daz = sprite[spritenum].z;
    h = ((tilesizy[sprite[spritenum].picnum]*sprite[spritenum].yrepeat)<<1);
    daz -= h;

    if( bg )
    {
        oldx = sprite[spritenum].x;
        oldy = sprite[spritenum].y;

        if( sprite[spritenum].xrepeat > 60 )
            retval = clipmove(&sprite[spritenum].x,&sprite[spritenum].y,&daz,&dasectnum,((xchange*TICSPERFRAME)<<11),((ychange*TICSPERFRAME)<<11),1024L,(4<<8),(4<<8),cliptype);
        else
        {
            cd = 192L;
            retval = clipmove(&sprite[spritenum].x,&sprite[spritenum].y,&daz,&dasectnum,((xchange*TICSPERFRAME)<<11),((ychange*TICSPERFRAME)<<11),cd,(4<<8),(4<<8),cliptype);
        }

        if( dasectnum < 0 || ( dasectnum >= 0 &&
            hittype[spritenum].actorstayput >= 0 && hittype[spritenum].actorstayput != dasectnum ) )
        {
                sprite[spritenum].x = oldx;
                sprite[spritenum].y = oldy;
                if(sector[dasectnum].lotag == 1)
                    sprite[spritenum].ang = (TRAND&2047);
                else if( (hittype[spritenum].temp_data[0]&3) == 1 )
                    sprite[spritenum].ang = (TRAND&2047);
                setsprite(spritenum,oldx,oldy,sprite[spritenum].z);
                if(dasectnum < 0) dasectnum = 0;
                return (16384+dasectnum);
        }
        if( (retval&49152) >= 32768 && (hittype[spritenum].cgg==0) ) sprite[spritenum].ang += 768;
    }
    else
    {
        if(sprite[spritenum].statnum == 4)
            retval =
                clipmove(&sprite[spritenum].x,&sprite[spritenum].y,&daz,&dasectnum,((xchange*TICSPERFRAME)<<11),((ychange*TICSPERFRAME)<<11),8L,(4<<8),(4<<8),cliptype);
        else
            retval =
                clipmove(&sprite[spritenum].x,&sprite[spritenum].y,&daz,&dasectnum,((xchange*TICSPERFRAME)<<11),((ychange*TICSPERFRAME)<<11),128L,(4<<8),(4<<8),cliptype);
    }

    if( dasectnum >= 0)
        if ( (dasectnum != sprite[spritenum].sectnum) )
            changespritesect(spritenum,dasectnum);
    daz = sprite[spritenum].z + ((zchange*TICSPERFRAME)>>3);
    if ((daz > hittype[spritenum].ceilingz) && (daz <= hittype[spritenum].floorz))
        sprite[spritenum].z = daz;
    else
        if (retval == 0)
            return(16384+dasectnum);

	return(retval);
}

short ssp(short i,unsigned long cliptype) //The set sprite function
{
    spritetype *s;
    long movetype;

    s = &sprite[i];

    movetype = movesprite(i,
        (s->xvel*(sintable[(s->ang+512)&2047]))>>14,
        (s->xvel*(sintable[s->ang&2047]))>>14,s->zvel,
        cliptype);

    return (movetype==0);
}

void insertspriteq(short i)
{
    if(spriteqamount > 0)
    {
        if(spriteq[spriteqloc] >= 0)
            sprite[spriteq[spriteqloc]].xrepeat = 0;
        spriteq[spriteqloc] = i;
        spriteqloc = (spriteqloc+1)%spriteqamount;
    }
    else sprite[i].xrepeat = sprite[i].yrepeat = 0;
}

#ifdef RANDCORRECT
void lotsofmoney(spritetype *s, short n)
{
    short i ,j;
    short r1, r2;
    for(i=n;i>0;i--)
    {
        r1 = TRAND;
        r2 = TRAND;
        j = EGS(s->sectnum,s->x,s->y,s->z-(r2%(47<<8)),1310,-32,8,8,r1&2047,0,0,0,5);
        sprite[j].cstat = TRAND&12;
    }
}

void lotsofmail(spritetype *s, short n)
{
    short i ,j;
    short r1, r2;
    for(i=n;i>0;i--)
    {
        r1 = TRAND;
        r2 = TRAND;
        j = EGS(s->sectnum,s->x,s->y,s->z-(r2%(47<<8)),1310,-32,8,8,r1&2047,0,0,0,5);
        sprite[j].cstat = TRAND&12;
    }
}

void lotsofpaper(spritetype *s, short n)
{
    short i ,j;
    short r1, r2;
    for(i=n;i>0;i--)
    {
        r1 = TRAND;
        r2 = TRAND;
        j = EGS(s->sectnum,s->x,s->y,s->z-(r2%(47<<8)),1310,-32,8,8,r1&2047,0,0,0,5);
        sprite[j].cstat = TRAND&12;
    }
}
#else
void lotsofmoney(spritetype *s, short n)
{
    short i ,j;
    for(i=n;i>0;i--)
    {
        j = EGS(s->sectnum,s->x,s->y,s->z-(TRAND%(47<<8)),MONEY,-32,8,8,TRAND&2047,0,0,0,5);
        sprite[j].cstat = TRAND&12;
    }
}

void lotsofmail(spritetype *s, short n)
{
    short i ,j;
    for(i=n;i>0;i--)
    {
        j = EGS(s->sectnum,s->x,s->y,s->z-(TRAND%(47<<8)),MONEY,-32,8,8,TRAND&2047,0,0,0,5);
        sprite[j].cstat = TRAND&12;
    }
}

void lotsofpaper(spritetype *s, short n)
{
    short i ,j;
    for(i=n;i>0;i--)
    {
        j = EGS(s->sectnum,s->x,s->y,s->z-(TRAND%(47<<8)),MONEY,-32,8,8,TRAND&2047,0,0,0,5);
        sprite[j].cstat = TRAND&12;
    }
}
#endif

void guts(spritetype *s,short gtype, short n, short p)
{
    long gutz,floorz;
    short i,a,j;
    char sx,sy;
    signed char pal;

    if(badguy(s) && s->xrepeat < 16)
        sx = sy = 8;
    else sx = sy = 32;

    gutz = s->z-(8<<8);
    floorz = getflorzofslope(s->sectnum,s->x,s->y);

    if( gutz > ( floorz-(8<<8) ) )
        gutz = floorz-(8<<8);

    if( badguy(s) && s->pal == 6)
        pal = 6;
#ifdef RRRA
    else if (s->picnum == MINION && s->pal == 8)
        pal = 8;
    else if (s->picnum == MINION && s->pal == 19)
        pal = 19;
#endif
    else pal = 0;

    for(j=0;j<n;j++)
    {
#ifdef RANDCORRECT
        short r1, r2, r3, r4, r5;
        a = TRAND&2047;
        r1 = TRAND;
        r2 = TRAND;
        r3 = TRAND;
        r4 = TRAND;
        r5 = TRAND;
        i = EGS(s->sectnum,s->x+(r5&255)-128,s->y+(r4&255)-128,gutz-(r3&8191),gtype,-32,sx>>1,sy>>1,a,48+(r2&31),-512-(r1&2047),ps[p].i,5);
#else
        a = TRAND&2047;
        i = EGS(s->sectnum,s->x+(TRAND&255)-128,s->y+(TRAND&255)-128,gutz-(TRAND&8191),gtype,-32,sx>>1,sy>>1,a,48+(TRAND&31),-512-(TRAND&2047),ps[p].i,5);
#endif
        if(pal == 6)
            sprite[i].pal = 6;
#ifdef RRRA
        else if(pal == 8)
            sprite[i].pal = 8;
        else if(pal == 19)
            sprite[i].pal = 19;
#endif
    }
}

void gutsdir(spritetype *s,short gtype, short n, short p)
{
    long gutz,floorz;
    short i,a,j;
    char sx,sy;

    if(badguy(s) && s->xrepeat < 16)
        sx = sy = 8;
    else sx = sy = 32;

    gutz = s->z-(8<<8);
    floorz = getflorzofslope(s->sectnum,s->x,s->y);

    if( gutz > ( floorz-(8<<8) ) )
        gutz = floorz-(8<<8);

    for(j=0;j<n;j++)
    {
#ifdef RANDCORRECT
        short r1, r2;
        a = TRAND&2047;
        r1 = TRAND;
        r2 = TRAND;
        i = EGS(s->sectnum,s->x,s->y,gutz,gtype,-32,sx,sy,a,256+(r2&127),-512-(r1&2047),ps[p].i,5);
#else
        a = TRAND&2047;
        i = EGS(s->sectnum,s->x,s->y,gutz,gtype,-32,sx,sy,a,256+(TRAND&127),-512-(TRAND&2047),ps[p].i,5);
#endif
    }
}

void setsectinterpolate(short i)
{
    long j, k, startwall,endwall;

    startwall = sector[SECT].wallptr;
    endwall = startwall+sector[SECT].wallnum;

    for(j=startwall;j<endwall;j++)
    {
        setinterpolation(&wall[j].x);
        setinterpolation(&wall[j].y);
        k = wall[j].nextwall;
        if(k >= 0)
        {
            setinterpolation(&wall[k].x);
            setinterpolation(&wall[k].y);
            k = wall[k].point2;
            setinterpolation(&wall[k].x);
            setinterpolation(&wall[k].y);
        }
    }
}

void clearsectinterpolate(short i)
{
    short j,startwall,endwall;

    startwall = sector[SECT].wallptr;
    endwall = startwall+sector[SECT].wallnum;
    for(j=startwall;j<endwall;j++)
    {
        stopinterpolation(&wall[j].x);
        stopinterpolation(&wall[j].y);
        if(wall[j].nextwall >= 0)
        {
            stopinterpolation(&wall[wall[j].nextwall].x);
            stopinterpolation(&wall[wall[j].nextwall].y);
        }
    }
}

void ms(short i)
{
    //T1,T2 and T3 are used for all the sector moving stuff!!!

    short startwall,endwall,x;
    long tx,ty,j,k;
    spritetype *s;

    s = &sprite[i];

    s->x += (s->xvel*(sintable[(s->ang+512)&2047]))>>14;
    s->y += (s->xvel*(sintable[s->ang&2047]))>>14;

    j = T2;
    k = T3;

    startwall = sector[s->sectnum].wallptr;
    endwall = startwall+sector[s->sectnum].wallnum;
    for(x=startwall;x<endwall;x++)
    {
        rotatepoint(
            0,0,
            msx[j],msy[j],
            k&2047,&tx,&ty);

        dragpoint(x,s->x+tx,s->y+ty);

        j++;
    }
}

#ifdef DESYNCCORRECT
/////Desync fix////
short fakejval = 0;
///////////////////
#endif

void movefta(void)
{
    long x, px, py, sx, sy;
    short i, j, wk, p, psect, ssect, nexti;
    spritetype *s;
    char uu;
    short bg;

#ifdef DESYNCCORRECT
    /////Desync fix////
    j = fakejval;
    ///////////////////
#endif

    i = headspritestat[2];
    while(i >= 0)
    {
        nexti = nextspritestat[i];

        s = &sprite[i];
        p = findplayer(s,&x);

        ssect = psect = s->sectnum;

        if(sprite[ps[p].i].extra > 0 )
        {
            if( x < 30000 )
            {
                hittype[i].timetosleep++;
                if( hittype[i].timetosleep >= (x>>8) )
                {
                    bg = badguy(s);
                    if(bg)
                    {
                        px = ps[p].oposx+64-(TRAND&127);
                        py = ps[p].oposy+64-(TRAND&127);
                        updatesector(px,py,&psect);
                        if(psect == -1)
                        {
                            i = nexti;
                            continue;
                        }
                        sx = s->x+64-(TRAND&127);
                        sy = s->y+64-(TRAND&127);
                        updatesector(px,py,&ssect);
                        if(ssect == -1)
                        {
                            i = nexti;
                            continue;
                        }
#ifdef RRRA
                        if(s->pal == 33 || s->picnum == COOT || s->picnum == COOTSTAYPUT || s->picnum == VIXEN || s->picnum == BIKER || s->picnum == BIKERB || s->picnum == BIKERBV2 || s->picnum == CHEER || s->picnum == CHEERB
                            || s->picnum == CHEERSTAYPUT || s->picnum == MINIONBOAT || s->picnum == HULKBOAT || s->picnum == CHEERBOAT || s->picnum == RABBIT || s->picnum == COOTPLAY || s->picnum == BILLYPLAY || s->picnum == MAKEOUT || s->picnum == MAMA
                            || (s->picnum == MINION && s->pal == 8))
#else
                        if(s->pal == 33 || s->picnum == VIXEN)
#endif
#ifdef RANDCORRECT
                        {
                            short r1, r2;
                            r1 = TRAND;
                            r2 = TRAND;
                            j = cansee(sx,sy,s->z-(r2%(52<<8)),s->sectnum,px,py,ps[p].oposz-(r1%(32<<8)),ps[p].cursectnum);
                        }
#else
                            j = cansee(sx,sy,s->z-(TRAND%(52<<8)),s->sectnum,px,py,ps[p].oposz-(TRAND%(32<<8)),ps[p].cursectnum);
#endif
                        else
                        {
                            if (sintable[(s->ang+512)&2047]*(px-sx)+sintable[s->ang&2047]*(py-sy) >= 0)
#ifdef RANDCORRECT
                            {
                                short r1, r2;
                                r1 = TRAND;
                                r2 = TRAND;
                                j = cansee(sx,sy,s->z-(r2%(52<<8)),s->sectnum,px,py,ps[p].oposz-(r1%(32<<8)),ps[p].cursectnum);
                            }
#else
                                j = cansee(sx,sy,s->z-(TRAND%(52<<8)),s->sectnum,px,py,ps[p].oposz-(TRAND%(32<<8)),ps[p].cursectnum);
#endif
                            else
                                j = 0;

                        }
                    }
                    else
                    {
#ifdef RANDCORRECT
                        short r1, r2;
                        r1 = TRAND;
                        r2 = TRAND;
                        j = cansee(s->x,s->y,s->z-((r2&31)<<8),s->sectnum,ps[p].oposx,ps[p].oposy,ps[p].oposz-((r1&31)<<8),ps[p].cursectnum);
#else
                        j = cansee(s->x,s->y,s->z-((TRAND&31)<<8),s->sectnum,ps[p].oposx,ps[p].oposy,ps[p].oposz-((TRAND&31)<<8),ps[p].cursectnum);
#endif
                    }

       //             j = 1;

                    if(j) switch(s->picnum)
                    {
                        case RUBBERCAN:
                        case EXPLODINGBARREL:
                        case WOODENHORSE:
                        case HORSEONSIDE:
                        case CANWITHSOMETHING:
                        case FIREBARREL:
                        case FIREVASE:
                        case NUKEBARREL:
                        case NUKEBARRELDENTED:
                        case NUKEBARRELLEAKED:
                            if (sector[s->sectnum].ceilingstat&1)
                                s->shade = sector[s->sectnum].ceilingshade;
                            else s->shade = sector[s->sectnum].floorshade;

                            hittype[i].timetosleep = 0;
                            changespritestat(i,6);
                            break;
                        default:
                            hittype[i].timetosleep = 0;
                            check_fta_sounds(i);
                            changespritestat(i,1);
                            break;
                    }
                    else hittype[i].timetosleep = 0;
                }
            }
            if( !j )
                if ( badguy( s ) )
            {
                if (sector[s->sectnum].ceilingstat&1)
                    s->shade = sector[s->sectnum].ceilingshade;
                else s->shade = sector[s->sectnum].floorshade;
#ifdef RRRA
                if(s->picnum != HEN || s->picnum != COW || s->picnum != PIG || s->picnum != DOGRUN || s->picnum != RABBIT)
#else
                if(s->picnum != HEN || s->picnum != COW || s->picnum != PIG || s->picnum != DOGRUN)
#endif
                    wk = wakeup(i, p);
                if (wk)
                {
                    hittype[i].timetosleep = 0;
                    check_fta_sounds(i);
                    changespritestat(i,1);
                }

            }
        }
        i = nexti;
    }
}

short ifhitsectors(short sectnum)
{
    short i;

    i = headspritestat[5];
    while(i >= 0)
    {
        if( PN == EXPLOSION2 || (PN == EXPLOSION3 && sectnum == SECT) )
            return i;
        i = nextspritestat[i];
    }
    return -1;
}