Exemplo n.º 1
0
void playsong(const char * song)
{
   int voice;
   int length;
   char * data;
   FILE * fp;
   
   fp = fopen(song, "rb");
   if (!fp) {
      fprintf(stderr, "Error opening %s\n", song);
      return;
   }
   
   fseek(fp, 0, SEEK_END);
   length = ftell(fp);
   if (length <= 0) {
      fclose(fp);
      return;
   }

   data = (char *) malloc(length);
   if (!data) {
      fclose(fp);
      return;
   }

   fseek(fp, 0, SEEK_SET);
   
   if (fread(data, length, 1, fp) != 1) {
      fclose(fp);
      free(data);
      return;
   }
   
   fclose(fp);
   
   voice = FX_PlayAuto(data, length, 0, 255, 255, 255, FX_MUSIC_PRIORITY, 1);
   if (voice >= FX_Ok) {
      while (FX_SoundActive(voice)) {
         ASS_Sleep(500);
      }
   } else {
      fprintf(stderr, "Error playing sound\n");
   }
   
   free(data);
}
Exemplo n.º 2
0
// NOTE: If v3df_follow == 1, x,y,z are considered literal coordinates
int
PlaySound(int num, int *x, int *y, int *z, Voc3D_Flags flags)
{
    VOC_INFOp vp;
    VOC3D_INFOp v3p;
    int pitch = 0;
    short angle, sound_dist;
    int tx, ty, tz;
    uint8_t priority;
    SPRITEp sp=NULL;

    // DEBUG
    //extern SWBOOL Pachinko_Win_Cheat;


    // Don't play game sounds when in menus
    //if (UsingMenus && (*x!=0 || *y!=0 || *z!=0)) return(-1);

    // Weed out parental lock sounds if PLock is active
    if (gs.ParentalLock || Global_PLock)
    {
        unsigned i;

        for (i=0; i<sizeof(PLocked_Sounds); i++)
        {
            if (num == PLocked_Sounds[i])
                return -1;
        }
    }

    if (Prediction)
        return -1;

    if (!gs.FxOn)
        return -1;

    PRODUCTION_ASSERT(num >= 0 && num < DIGI_MAX);

    // Reset voice
    voice = -1;

    // This is used for updating looping sounds in Update3DSounds
    if (Use_SoundSpriteNum && SoundSpriteNum >= 0)
    {
        ASSERT(SoundSpriteNum >= 0 && SoundSpriteNum < MAXSPRITES);
        sp = &sprite[SoundSpriteNum];
    }

    if (gs.Ambient && TEST(flags,v3df_ambient) && !TEST(flags,v3df_nolookup))  // Look for invalid ambient numbers
    {
        if (num < 0 || num > MAX_AMBIENT_SOUNDS)
        {
            sprintf(ds,"Invalid or out of range ambient sound number %d\n",num);
            PutStringInfo(Player+screenpeek, ds);
            return -1;
        }
    }


    // Call queue management to add sound to play list.
    // 3D sound manager will update playing sound 10x per second until
    // the sound ends, at which time it is removed from both the 3D
    // sound list as well as the actual cache.
    v3p = Insert3DSound();

    // If the ambient flag is set, do a name conversion to point to actual
    // digital sound entry.
    v3p->num = num;
    v3p->priority = 0;
    v3p->FX_Ok = FALSE; // Hasn't played yet

    if (gs.Ambient && TEST(flags,v3df_ambient) && !TEST(flags,v3df_nolookup))
    {
        v3p->maxtics = STD_RANDOM_RANGE(ambarray[num].maxtics);
        flags |= ambarray[num].ambient_flags;   // Add to flags if any
        num = ambarray[num].diginame;
    }

    PRODUCTION_ASSERT(num >= 0 && num < DIGI_MAX);


    // Assign voc to voc pointer
    vp = &voc[num];
    if (UsingMenus && *x==0 && *y==0 && *z==0)  // Menus sound outdo everything
        priority = 100;
    else
        priority = vp->priority;
    v3p->vp = vp;

    // Assign voc info to 3d struct for future reference
    v3p->x = x;
    v3p->y = y;
    v3p->z = z;
    v3p->fx = *x;
    v3p->fy = *y;
    v3p->fz = *z;
    v3p->flags = flags;

    if (flags & v3df_follow)
    {
        tx = *x;
        ty = *y;
        if (!z)
            tz = 0;                     // Some sound calls don't have a z
        // value
        else
            tz = *z;
    }
    else
    {
        // Don't use pointers to coordinate values.
        tx = v3p->fx;
        ty = v3p->fy;
        tz = v3p->fz;
    }

    // Special case stuff for sounds being played in a level
    if (*x==0 && *y==0 && *z==0)
        tx = ty = tz = 0;

    if ((vp->voc_flags & vf_loop) && Use_SoundSpriteNum && SoundSpriteNum >= 0 && sp)
    {
        tx=sp->x;
        ty=sp->y;
        tz=sp->z;
        //CON_Message("Using sp to set tx=%ld,ty=%ld,tz=%ld",tx,ty,tz);
    }

    // Calculate sound angle
    if (flags & v3df_dontpan)               // If true, don't do panning
        angle = 0;
    else
        angle = SoundAngle(tx, ty);

    // Calculate sound distance
    if (tx == 0 && ty == 0 && tz == 0)
        sound_dist = 255;  // Special case for menus sounds,etc.
    else
        sound_dist = SoundDist(tx, ty, tz, vp->voc_distance);

    v3p->doplr_delta = sound_dist;      // Save of distance for doppler
    // effect

//  //DSPRINTF(ds,"sound dist = %d\n",sound_dist);
//  MONO_PRINT(ds);

    // Can the ambient sound see the player?  If not, tone it down some.
    if ((vp->voc_flags & vf_loop) && Use_SoundSpriteNum && SoundSpriteNum >= 0)
    {
        PLAYERp pp = Player+screenpeek;

        //MONO_PRINT("PlaySound:Checking sound cansee");
        if (!FAFcansee(tx, ty, tz, sp->sectnum,pp->posx, pp->posy, pp->posz, pp->cursectnum))
        {
            //MONO_PRINT("PlaySound:Reducing sound distance");
            sound_dist += ((sound_dist/2)+(sound_dist/4));  // Play more quietly
            if (sound_dist > 255) sound_dist = 255;

            // Special Cases
            if (num == DIGI_WHIPME) sound_dist = 255;
        }
    }

    // Assign ambient priorities based on distance
    if (gs.Ambient && TEST(flags, v3df_ambient))
    {
        v3p->priority = v3p->vp->priority - (sound_dist / 26);
        priority = v3p->priority;
    }

    if (!CacheSound(num, CACHE_SOUND_PLAY))
    {
        v3p->flags = v3df_kill;
        v3p->handle = -1;
        v3p->dist = 0;
        v3p->deleted = TRUE;            // Sound init failed, remove it!
        return -1;
    }

    LockSound(num);

    if (sound_dist < 5)
        angle = 0;

    // Check for pitch bending
    if (vp->pitch_lo > vp->pitch_hi)
        ASSERT(vp->pitch_lo <= vp->pitch_hi);

    if (vp->pitch_hi == vp->pitch_lo)
        pitch = vp->pitch_lo;
    else if (vp->pitch_hi != vp->pitch_lo)
        pitch = vp->pitch_lo + (STD_RANDOM_RANGE(vp->pitch_hi - vp->pitch_lo));

#if 0
    // DEBUG
    if (Pachinko_Win_Cheat)
    {
        CheckSndData(__FILE__, __LINE__);
        Pachinko_Win_Cheat = FALSE;
        CON_Message("S O U N D S   C H E C K E D");
    }
#endif

    // Request playback and play it as a looping sound if flag is set.
    if (vp->voc_flags & vf_loop)
    {
        short loopvol=0;

        if ((loopvol = 255-sound_dist) <= 0)
            loopvol = 0;

        if (sound_dist < 255 || (flags & v3df_init))
        {
            voice = FX_PlayLoopedAuto((char *)vp->data, vp->datalen, 0, 0,
                                      pitch, loopvol, loopvol, loopvol, priority, num);
        }
        else
            voice = -1;

    }
    else
    //if(!flags & v3df_init)  // If not initing sound, play it
    if (tx==0 && ty==0 && tz==0)     // It's a non-inlevel sound
    {
        voice = FX_PlayAuto((char *)vp->data, vp->datalen, pitch, 255, 255, 255, priority, num);
    }
    else     // It's a 3d sound
    {
        if (sound_dist < 255)
        {
            voice = FX_PlayAuto3D((char *)vp->data, vp->datalen, FX_ONESHOT, pitch, angle, sound_dist, priority, num);
        }
        else
            voice = -1;
    }

    // If sound played, update our counter
    if (voice > FX_Ok)
    {
        //vp->playing++;
        v3p->FX_Ok = TRUE;
    }
    else
    {
        vp->lock--;
    }

    // Assign voc info to 3d struct for future reference
    v3p->handle = voice;                // Save the current voc handle in struct
    v3p->dist = sound_dist;
    v3p->tics = 0;                      // Reset tics
    if (flags & v3df_init)
        v3p->flags ^= v3df_init;        // Turn init off now

    return voice;
}