mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-27 22:42:57 +00:00
SVN r44 (trunk)
This commit is contained in:
parent
4dd936e438
commit
07f35a7008
22 changed files with 423 additions and 119 deletions
97
FLAC/private/float.h
Normal file
97
FLAC/private/float.h
Normal file
|
@ -0,0 +1,97 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2004,2005 Josh Coalson
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__FLOAT_H
|
||||
#define FLAC__PRIVATE__FLOAT_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "FLAC/ordinals.h"
|
||||
|
||||
/*
|
||||
* These typedefs make it easier to ensure that integer versions of
|
||||
* the library really only contain integer operations. All the code
|
||||
* in libFLAC should use FLAC__float and FLAC__double in place of
|
||||
* float and double, and be protected by checks of the macro
|
||||
* FLAC__INTEGER_ONLY_LIBRARY.
|
||||
*
|
||||
* FLAC__real is the basic floating point type used in LPC analysis.
|
||||
*/
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
typedef double FLAC__double;
|
||||
typedef float FLAC__float;
|
||||
/*
|
||||
* WATCHOUT: changing FLAC__real will change the signatures of many
|
||||
* functions that have assembly language equivalents and break them.
|
||||
*/
|
||||
typedef float FLAC__real;
|
||||
#else
|
||||
/*
|
||||
* The convention for FLAC__fixedpoint is to use the upper 16 bits
|
||||
* for the integer part and lower 16 bits for the fractional part.
|
||||
*/
|
||||
typedef FLAC__int32 FLAC__fixedpoint;
|
||||
extern const FLAC__fixedpoint FLAC__FP_ZERO;
|
||||
extern const FLAC__fixedpoint FLAC__FP_ONE_HALF;
|
||||
extern const FLAC__fixedpoint FLAC__FP_ONE;
|
||||
extern const FLAC__fixedpoint FLAC__FP_LN2;
|
||||
extern const FLAC__fixedpoint FLAC__FP_E;
|
||||
|
||||
#define FLAC__fixedpoint_trunc(x) ((x)>>16)
|
||||
|
||||
#define FLAC__fixedpoint_mul(x, y) ( (FLAC__fixedpoint) ( ((FLAC__int64)(x)*(FLAC__int64)(y)) >> 16 ) )
|
||||
|
||||
#define FLAC__fixedpoint_div(x, y) ( (FLAC__fixedpoint) ( ( ((FLAC__int64)(x)<<32) / (FLAC__int64)(y) ) >> 16 ) )
|
||||
|
||||
/*
|
||||
* FLAC__fixedpoint_log2()
|
||||
* --------------------------------------------------------------------
|
||||
* Returns the base-2 logarithm of the fixed-point number 'x' using an
|
||||
* algorithm by Knuth for x >= 1.0
|
||||
*
|
||||
* 'fracbits' is the number of fractional bits of 'x'. 'fracbits' must
|
||||
* be < 32 and evenly divisible by 4 (0 is OK but not very precise).
|
||||
*
|
||||
* 'precision' roughly limits the number of iterations that are done;
|
||||
* use (unsigned)(-1) for maximum precision.
|
||||
*
|
||||
* If 'x' is less than one -- that is, x < (1<<fracbits) -- then this
|
||||
* function will punt and return 0.
|
||||
*
|
||||
* The return value will also have 'fracbits' fractional bits.
|
||||
*/
|
||||
FLAC__uint32 FLAC__fixedpoint_log2(FLAC__uint32 x, unsigned fracbits, unsigned precision);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,3 +1,12 @@
|
|||
April 14, 2006 (Changes by Graf Zahl)
|
||||
- Added the missing file 'flac/private/float.h' to the repository.
|
||||
- Added: In preparation for Zip-support the sound code has to be able to
|
||||
load music data from memory, not just from files.
|
||||
- Re-added I_SetMusicVolume to optionally reduce the music volume in Strife
|
||||
conversations.
|
||||
- Fixed: The total game time must not be restored when loading a snapshot
|
||||
during a hub transition.
|
||||
|
||||
April 13, 2006
|
||||
- Fix farchive.cpp swappers for GCC again. Now that they use entirely integer
|
||||
math, they should work with all GCC versions.
|
||||
|
|
|
@ -2290,7 +2290,7 @@ void G_AirControlChanged ()
|
|||
|
||||
void G_SerializeLevel (FArchive &arc, bool hubLoad)
|
||||
{
|
||||
int i;
|
||||
int i = level.totaltime;
|
||||
|
||||
arc << level.flags
|
||||
<< level.fadeto
|
||||
|
@ -2300,7 +2300,11 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad)
|
|||
<< level.gravity
|
||||
<< level.aircontrol
|
||||
<< level.maptime
|
||||
<< level.totaltime;
|
||||
<< i;
|
||||
|
||||
// Hub transitions must keep the current total time
|
||||
if (!hubLoad)
|
||||
level.totaltime=i;
|
||||
|
||||
if (arc.IsStoring ())
|
||||
{
|
||||
|
|
|
@ -21,7 +21,7 @@ EXTERN_CVAR (Bool, opl_onechip)
|
|||
|
||||
static OPLmusicBlock *BlockForStats;
|
||||
|
||||
OPLmusicBlock::OPLmusicBlock (FILE *file, int len, int rate, int maxSamples)
|
||||
OPLmusicBlock::OPLmusicBlock (FILE *file, char * musiccache, int len, int rate, int maxSamples)
|
||||
: SampleRate (rate), NextTickIn (0), Looping (false), ScoreLen (len)
|
||||
{
|
||||
scoredata = NULL;
|
||||
|
@ -40,7 +40,22 @@ OPLmusicBlock::OPLmusicBlock (FILE *file, int len, int rate, int maxSamples)
|
|||
#endif
|
||||
|
||||
scoredata = new BYTE[len];
|
||||
if (fread (scoredata, 1, len, file) != (size_t)len || io->OPLinit (TwoChips + 1, rate))
|
||||
|
||||
if (file)
|
||||
{
|
||||
if (fread (scoredata, 1, len, file) != (size_t)len)
|
||||
{
|
||||
delete[] scoredata;
|
||||
scoredata = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(scoredata, &musiccache[0], len);
|
||||
}
|
||||
|
||||
if (io->OPLinit (TwoChips + 1, rate))
|
||||
{
|
||||
delete[] scoredata;
|
||||
scoredata = NULL;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
class OPLmusicBlock : public musicBlock
|
||||
{
|
||||
public:
|
||||
OPLmusicBlock (FILE *file, int len, int rate, int maxSamples);
|
||||
OPLmusicBlock (FILE *file, char * musiccache, int len, int rate, int maxSamples);
|
||||
~OPLmusicBlock ();
|
||||
bool IsValid () const;
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "a_strifeglobal.h"
|
||||
#include "a_keys.h"
|
||||
#include "p_enemy.h"
|
||||
#include "sound/i_music.h"
|
||||
|
||||
// The conversations as they exist inside a SCRIPTxx lump.
|
||||
struct Response
|
||||
|
@ -664,6 +665,12 @@ static void TakeStrifeItem (const TypeInfo *itemtype, int amount)
|
|||
}
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Float, dlg_musicvolume, 1.0f, CVAR_ARCHIVE)
|
||||
{
|
||||
if (self < 0.f) self = 0.f;
|
||||
else if (self > 1.f) self = 1.f;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// P_StartConversation
|
||||
|
@ -723,6 +730,7 @@ void P_StartConversation (AActor *npc, AActor *pc)
|
|||
|
||||
if (CurNode->SpeakerVoice != 0)
|
||||
{
|
||||
I_SetMusicVolume(dlg_musicvolume);
|
||||
S_SoundID (npc, CHAN_VOICE, CurNode->SpeakerVoice, 1, ATTN_NORM);
|
||||
}
|
||||
|
||||
|
@ -1043,6 +1051,7 @@ static void PickConversationReply ()
|
|||
}
|
||||
|
||||
ConversationNPC->angle = ConversationNPCAngle;
|
||||
I_SetMusicVolume(1.f);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -1075,5 +1084,6 @@ void CleanupConversationMenu ()
|
|||
DialogueLines = NULL;
|
||||
}
|
||||
ConversationItems.Clear ();
|
||||
I_SetMusicVolume(1.f);
|
||||
}
|
||||
|
||||
|
|
|
@ -265,8 +265,8 @@ void S_NoiseDebug (void)
|
|||
BorderNeedRefresh = screen->GetPageCount ();
|
||||
}
|
||||
|
||||
static string LastLocalSndInfo = "";
|
||||
static string LastLocalSndSeq = "";
|
||||
static string LastLocalSndInfo;
|
||||
static string LastLocalSndSeq;
|
||||
void S_AddLocalSndInfo(int lump);
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1414,6 +1414,8 @@ bool S_StartMusic (const char *m_id)
|
|||
// specified, it will only be played if the specified CD is in a drive.
|
||||
//==========================================================================
|
||||
|
||||
TArray<char> musiccache;
|
||||
|
||||
bool S_ChangeMusic (const char *musicname, int order, bool looping, bool force)
|
||||
{
|
||||
if (!force && PlayList)
|
||||
|
@ -1467,8 +1469,24 @@ bool S_ChangeMusic (const char *musicname, int order, bool looping, bool force)
|
|||
Printf ("Music \"%s\" not found\n", musicname);
|
||||
return false;
|
||||
}
|
||||
offset = Wads.GetLumpOffset (lumpnum);
|
||||
length = Wads.LumpLength (lumpnum);
|
||||
if (!Wads.IsUncompressedFile(lumpnum))
|
||||
{
|
||||
// We must cache the music data and use it from memory.
|
||||
|
||||
// shut down old music before reallocating and overwriting the cache!
|
||||
S_StopMusic (true);
|
||||
|
||||
offset = -1; // this tells the low level code that the music
|
||||
// is being used from memory
|
||||
length = Wads.LumpLength (lumpnum);
|
||||
musiccache.Resize(length);
|
||||
Wads.ReadLump(lumpnum, &musiccache[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = Wads.GetLumpOffset (lumpnum);
|
||||
length = Wads.LumpLength (lumpnum);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1480,13 +1498,27 @@ bool S_ChangeMusic (const char *musicname, int order, bool looping, bool force)
|
|||
S_StopMusic (true);
|
||||
|
||||
// load & register it
|
||||
|
||||
// Note by Graf Zahl: S_StopMusic NULLs this variable so there's nothing to delete anymore!
|
||||
/*
|
||||
if (mus_playing.name)
|
||||
{
|
||||
delete[] mus_playing.name;
|
||||
}
|
||||
mus_playing.handle = I_RegisterSong (lumpnum != -1 ?
|
||||
Wads.GetWadFullName (Wads.GetLumpFile (lumpnum)) :
|
||||
musicname, offset, length);
|
||||
*/
|
||||
|
||||
if (offset!=-1)
|
||||
{
|
||||
mus_playing.handle = I_RegisterSong (lumpnum != -1 ?
|
||||
Wads.GetWadFullName (Wads.GetLumpFile (lumpnum)) :
|
||||
musicname, NULL, offset, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
// musiccache is used globally because otherwise I'd have to pass
|
||||
// it as a parameter through several layers of code.
|
||||
mus_playing.handle = I_RegisterSong (NULL, &musiccache[0], -1, length);
|
||||
}
|
||||
}
|
||||
|
||||
mus_playing.loop = looping;
|
||||
|
|
|
@ -611,11 +611,19 @@ SoundStream *FMODSoundRenderer::CreateStream (SoundStreamCallback callback, int
|
|||
return NULL;
|
||||
}
|
||||
|
||||
SoundStream *FMODSoundRenderer::OpenStream (const char *filename, int flags, int offset, int length)
|
||||
SoundStream *FMODSoundRenderer::OpenStream (const char *filename_or_data, int flags, int offset, int length)
|
||||
{
|
||||
unsigned int mode = FSOUND_NORMAL | FSOUND_2D;
|
||||
if (flags & SoundStream::Loop) mode |= FSOUND_LOOP_NORMAL;
|
||||
FSOUND_STREAM *stream = FSOUND_Stream_Open (filename, mode, offset, length);
|
||||
FSOUND_STREAM *stream;
|
||||
|
||||
if (offset==-1)
|
||||
{
|
||||
mode |= FSOUND_LOADMEMORY;
|
||||
offset=0;
|
||||
}
|
||||
stream = FSOUND_Stream_Open (filename_or_data, mode, offset, length);
|
||||
|
||||
if (stream != NULL)
|
||||
{
|
||||
return new FMODStreamCapsule (stream);
|
||||
|
@ -623,9 +631,19 @@ SoundStream *FMODSoundRenderer::OpenStream (const char *filename, int flags, int
|
|||
return NULL;
|
||||
}
|
||||
|
||||
SoundTrackerModule *FMODSoundRenderer::OpenModule (const char *filename, int offset, int length)
|
||||
SoundTrackerModule *FMODSoundRenderer::OpenModule (const char *filename_or_data, int offset, int length)
|
||||
{
|
||||
FMUSIC_MODULE *mod = FMUSIC_LoadSongEx (filename, offset, length, FSOUND_LOOP_NORMAL, NULL, 0);
|
||||
FMUSIC_MODULE *mod;
|
||||
|
||||
int mode = FSOUND_LOOP_NORMAL;
|
||||
if (offset==-1)
|
||||
{
|
||||
mode |= FSOUND_LOADMEMORY;
|
||||
offset=0;
|
||||
}
|
||||
|
||||
mod = FMUSIC_LoadSongEx (filename_or_data, offset, length, mode, NULL, 0);
|
||||
|
||||
if (mod != NULL)
|
||||
{
|
||||
return new FMUSICCapsule (mod);
|
||||
|
|
|
@ -84,6 +84,7 @@ static bool MusicDown = true;
|
|||
MusInfo *currSong;
|
||||
int nomusic = 0;
|
||||
float relative_volume = 1.f;
|
||||
float saved_relative_volume = 1.0f; // this could be used to implement an ACS FadeMusic function
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -159,7 +160,7 @@ void I_PlaySong (void *handle, int _looping, float rel_vol)
|
|||
if (!info || nomusic)
|
||||
return;
|
||||
|
||||
relative_volume = rel_vol;
|
||||
saved_relative_volume = relative_volume = rel_vol;
|
||||
info->Stop ();
|
||||
info->Play (_looping ? true : false);
|
||||
|
||||
|
@ -207,7 +208,7 @@ void I_UnRegisterSong (void *handle)
|
|||
}
|
||||
}
|
||||
|
||||
void *I_RegisterSong (const char *filename, int offset, int len)
|
||||
void *I_RegisterSong (const char *filename, char * musiccache, int offset, int len)
|
||||
{
|
||||
FILE *file;
|
||||
MusInfo *info = NULL;
|
||||
|
@ -218,63 +219,72 @@ void *I_RegisterSong (const char *filename, int offset, int len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
file = fopen (filename, "rb");
|
||||
if (file == NULL)
|
||||
if (offset!=-1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
file = fopen (filename, "rb");
|
||||
if (file == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (len == 0 && offset == 0)
|
||||
{
|
||||
fseek (file, 0, SEEK_END);
|
||||
len = ftell (file);
|
||||
fseek (file, 0, SEEK_SET);
|
||||
}
|
||||
else
|
||||
{
|
||||
fseek (file, offset, SEEK_SET);
|
||||
}
|
||||
if (len == 0 && offset == 0)
|
||||
{
|
||||
fseek (file, 0, SEEK_END);
|
||||
len = ftell (file);
|
||||
fseek (file, 0, SEEK_SET);
|
||||
}
|
||||
else
|
||||
{
|
||||
fseek (file, offset, SEEK_SET);
|
||||
}
|
||||
|
||||
if (fread (&id, 4, 1, file) != 1)
|
||||
{
|
||||
fclose (file);
|
||||
return 0;
|
||||
if (fread (&id, 4, 1, file) != 1)
|
||||
{
|
||||
fclose (file);
|
||||
return 0;
|
||||
}
|
||||
fseek (file, -4, SEEK_CUR);
|
||||
}
|
||||
else
|
||||
{
|
||||
file = NULL;
|
||||
memcpy(&id, &musiccache[0], 4);
|
||||
}
|
||||
fseek (file, -4, SEEK_CUR);
|
||||
|
||||
// Check for MUS format
|
||||
if (id == MAKE_ID('M','U','S',0x1a))
|
||||
{
|
||||
if (GSnd != NULL && opl_enable)
|
||||
{
|
||||
info = new OPLMUSSong (file, len);
|
||||
info = new OPLMUSSong (file, musiccache, len);
|
||||
}
|
||||
if (info == NULL)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (snd_mididevice != -2)
|
||||
{
|
||||
info = new MUSSong2 (file, len);
|
||||
info = new MUSSong2 (file, musiccache, len);
|
||||
}
|
||||
else if (GSnd != NULL)
|
||||
#endif // _WIN32
|
||||
{
|
||||
info = new TimiditySong (file, len);
|
||||
info = new TimiditySong (file, musiccache, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check for MIDI format
|
||||
else if (id == MAKE_ID('M','T','h','d'))
|
||||
{
|
||||
// This is a midi file
|
||||
#ifdef _WIN32
|
||||
if (snd_mididevice != -2)
|
||||
{
|
||||
info = new MIDISong2 (file, len);
|
||||
info = new MIDISong2 (file, musiccache, len);
|
||||
}
|
||||
else if (GSnd != NULL)
|
||||
#endif // _WIN32
|
||||
{
|
||||
info = new TimiditySong (file, len);
|
||||
info = new TimiditySong (file, musiccache, len);
|
||||
}
|
||||
}
|
||||
// Check for SPC format
|
||||
|
@ -283,22 +293,32 @@ void *I_RegisterSong (const char *filename, int offset, int len)
|
|||
{
|
||||
char header[0x23];
|
||||
|
||||
if (fread (header, 1, 0x23, file) != 0x23)
|
||||
if (file != NULL)
|
||||
{
|
||||
fclose (file);
|
||||
return 0;
|
||||
if (fread (header, 1, 0x23, file) != 0x23)
|
||||
{
|
||||
fclose (file);
|
||||
return 0;
|
||||
}
|
||||
fseek (file, -0x23, SEEK_CUR);
|
||||
}
|
||||
fseek (file, -0x23, SEEK_CUR);
|
||||
if (strncmp (header+4, "-SPC700 Sound File Data", 23) == 0)
|
||||
else
|
||||
{
|
||||
info = new SPCSong (file, len);
|
||||
memcpy(header, musiccache, 0x23);
|
||||
}
|
||||
|
||||
if (strncmp (header+4, "-SPC700 Sound File Data", 23) == 0 &&
|
||||
header[0x21] == '\x1a' &&
|
||||
header[0x22] == '\x1a')
|
||||
{
|
||||
info = new SPCSong (file, musiccache, len);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// Check for FLAC format
|
||||
else if (id == MAKE_ID('f','L','a','C'))
|
||||
{
|
||||
info = new FLACSong (file, len);
|
||||
info = new FLACSong (file, musiccache, len);
|
||||
file = NULL;
|
||||
}
|
||||
// Check for RDosPlay raw OPL format
|
||||
|
@ -306,15 +326,23 @@ void *I_RegisterSong (const char *filename, int offset, int len)
|
|||
{
|
||||
DWORD fullsig[2];
|
||||
|
||||
if (fread (fullsig, 4, 2, file) != 2)
|
||||
if (file != NULL)
|
||||
{
|
||||
fclose (file);
|
||||
return 0;
|
||||
if (fread (fullsig, 4, 2, file) != 2)
|
||||
{
|
||||
fclose (file);
|
||||
return 0;
|
||||
}
|
||||
fseek (file, -8, SEEK_CUR);
|
||||
}
|
||||
fseek (file, -8, SEEK_CUR);
|
||||
else
|
||||
{
|
||||
memcpy(fullsig, musiccache, 8);
|
||||
}
|
||||
|
||||
if (fullsig[1] == MAKE_ID('D','A','T','A'))
|
||||
{
|
||||
info = new OPLMUSSong (file, len);
|
||||
info = new OPLMUSSong (file, musiccache, len);
|
||||
}
|
||||
}
|
||||
// Check for Martin Fernandez's modified IMF format
|
||||
|
@ -322,15 +350,22 @@ void *I_RegisterSong (const char *filename, int offset, int len)
|
|||
{
|
||||
char fullhead[6];
|
||||
|
||||
if (fread (fullhead, 1, 6, file) != 6)
|
||||
if (file != NULL)
|
||||
{
|
||||
fclose (file);
|
||||
return 0;
|
||||
if (fread (fullhead, 1, 6, file) != 6)
|
||||
{
|
||||
fclose (file);
|
||||
return 0;
|
||||
}
|
||||
fseek (file, -6, SEEK_CUR);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(fullhead, musiccache, 6);
|
||||
}
|
||||
fseek (file, -6, SEEK_CUR);
|
||||
if (fullhead[4] == 'B' && fullhead[5] == 1)
|
||||
{
|
||||
info = new OPLMUSSong (file, len);
|
||||
info = new OPLMUSSong (file, musiccache, len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -339,20 +374,23 @@ void *I_RegisterSong (const char *filename, int offset, int len)
|
|||
// Check for CDDA "format"
|
||||
if (id == (('R')|(('I')<<8)|(('F')<<16)|(('F')<<24)))
|
||||
{
|
||||
DWORD subid;
|
||||
|
||||
fseek (file, 8, SEEK_CUR);
|
||||
if (fread (&subid, 4, 1, file) != 1)
|
||||
if (file != NULL)
|
||||
{
|
||||
fclose (file);
|
||||
return 0;
|
||||
}
|
||||
fseek (file, -12, SEEK_CUR);
|
||||
DWORD subid;
|
||||
|
||||
if (subid == (('C')|(('D')<<8)|(('D')<<16)|(('A')<<24)))
|
||||
{
|
||||
// This is a CDDA file
|
||||
info = new CDDAFile (file, len);
|
||||
fseek (file, 8, SEEK_CUR);
|
||||
if (fread (&subid, 4, 1, file) != 1)
|
||||
{
|
||||
fclose (file);
|
||||
return 0;
|
||||
}
|
||||
fseek (file, -12, SEEK_CUR);
|
||||
|
||||
if (subid == (('C')|(('D')<<8)|(('D')<<16)|(('A')<<24)))
|
||||
{
|
||||
// This is a CDDA file
|
||||
info = new CDDAFile (file, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -363,13 +401,13 @@ void *I_RegisterSong (const char *filename, int offset, int len)
|
|||
if (info == NULL && GSnd != NULL && len >= 1024)
|
||||
{
|
||||
// First try loading it as MOD, then as a stream
|
||||
fclose (file);
|
||||
if (file != NULL) fclose (file);
|
||||
file = NULL;
|
||||
info = new MODSong (filename, offset, len);
|
||||
info = new MODSong (offset>=0? filename : musiccache, offset, len);
|
||||
if (!info->IsValid ())
|
||||
{
|
||||
delete info;
|
||||
info = new StreamSong (filename, offset, len);
|
||||
info = new StreamSong (offset>=0? filename : musiccache, offset, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -416,6 +454,17 @@ bool I_SetSongPosition (void *handle, int order)
|
|||
return info ? info->SetPosition (order) : false;
|
||||
}
|
||||
|
||||
// Sets relative music volume. Takes $musicvolume in SNDINFO into consideration
|
||||
void I_SetMusicVolume (float factor)
|
||||
{
|
||||
factor = clamp<float>(factor, 0, 2.0f);
|
||||
relative_volume = saved_relative_volume * factor;
|
||||
#ifdef _WIN32
|
||||
snd_midivolume.Callback();
|
||||
#endif
|
||||
snd_musicvolume.Callback();
|
||||
}
|
||||
|
||||
CCMD(testmusicvol)
|
||||
{
|
||||
if (argv.argc() > 1)
|
||||
|
|
|
@ -53,7 +53,7 @@ void I_PauseSong (void *handle);
|
|||
void I_ResumeSong (void *handle);
|
||||
|
||||
// Registers a song handle to song data.
|
||||
void *I_RegisterSong (const char *file, int offset, int length);
|
||||
void *I_RegisterSong (const char *file, char * musiccache, int offset, int length);
|
||||
void *I_RegisterCDSong (int track, int cdid = 0);
|
||||
|
||||
// Called by anything that wishes to start music.
|
||||
|
|
|
@ -57,7 +57,7 @@ public:
|
|||
class MUSSong2 : public MusInfo
|
||||
{
|
||||
public:
|
||||
MUSSong2 (FILE *file, int length);
|
||||
MUSSong2 (FILE *file, char * musiccache, int length);
|
||||
~MUSSong2 ();
|
||||
|
||||
void SetVolume (float volume);
|
||||
|
@ -102,7 +102,7 @@ protected:
|
|||
class MIDISong2 : public MusInfo
|
||||
{
|
||||
public:
|
||||
MIDISong2 (FILE *file, int length);
|
||||
MIDISong2 (FILE *file, char * musiccache, int length);
|
||||
~MIDISong2 ();
|
||||
|
||||
void SetVolume (float volume);
|
||||
|
@ -204,7 +204,7 @@ typedef void *(__stdcall *EmuAPU_TYPE) (void *, DWORD, BYTE);
|
|||
class SPCSong : public StreamSong
|
||||
{
|
||||
public:
|
||||
SPCSong (FILE *file, int length);
|
||||
SPCSong (FILE *file, char * musiccache, int length);
|
||||
~SPCSong ();
|
||||
void Play (bool looping);
|
||||
bool IsPlaying ();
|
||||
|
@ -241,7 +241,7 @@ protected:
|
|||
class TimiditySong : public StreamSong
|
||||
{
|
||||
public:
|
||||
TimiditySong (FILE *file, int length);
|
||||
TimiditySong (FILE *file, char * musiccache, int length);
|
||||
~TimiditySong ();
|
||||
void Play (bool looping);
|
||||
void Stop ();
|
||||
|
@ -278,7 +278,7 @@ protected:
|
|||
class OPLMUSSong : public StreamSong
|
||||
{
|
||||
public:
|
||||
OPLMUSSong (FILE *file, int length);
|
||||
OPLMUSSong (FILE *file, char * musiccache, int length);
|
||||
~OPLMUSSong ();
|
||||
void Play (bool looping);
|
||||
bool IsPlaying ();
|
||||
|
@ -296,7 +296,7 @@ protected:
|
|||
class FLACSong : public StreamSong
|
||||
{
|
||||
public:
|
||||
FLACSong (FILE *file, int length);
|
||||
FLACSong (FILE *file, char * musiccache, int length);
|
||||
~FLACSong ();
|
||||
void Play (bool looping);
|
||||
bool IsPlaying ();
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
class FLACSong::FLACStreamer : protected FLAC::Decoder::Stream
|
||||
{
|
||||
public:
|
||||
FLACStreamer (FILE *file, int length);
|
||||
FLACStreamer (FILE *file, char * musiccache, int length);
|
||||
~FLACStreamer ();
|
||||
|
||||
bool ServiceStream (void *buff, int len, bool loop);
|
||||
|
@ -24,7 +24,7 @@ protected:
|
|||
|
||||
void CopyToStream (void *&sbuff, FLAC__int32 **buffer, size_t ofs, size_t samples);
|
||||
|
||||
FileReader File;
|
||||
FileReader *File;
|
||||
long StartPos, EndPos;
|
||||
|
||||
FLAC__int32 *SamplePool[2];
|
||||
|
@ -36,10 +36,10 @@ protected:
|
|||
size_t SLen;
|
||||
};
|
||||
|
||||
FLACSong::FLACSong (FILE *file, int length)
|
||||
FLACSong::FLACSong (FILE *file, char * musiccache, int length)
|
||||
: State (NULL)
|
||||
{
|
||||
State = new FLACStreamer (file, length);
|
||||
State = new FLACStreamer (file, musiccache, length);
|
||||
|
||||
if (State->NumChannels > 0 && State->SampleBits > 0 && State->SampleRate > 0)
|
||||
{
|
||||
|
@ -107,17 +107,25 @@ bool FLACSong::FillStream (SoundStream *stream, void *buff, int len, void *userd
|
|||
return song->State->ServiceStream (buff, len, song->m_Looping);
|
||||
}
|
||||
|
||||
FLACSong::FLACStreamer::FLACStreamer (FILE *iofile, int length)
|
||||
FLACSong::FLACStreamer::FLACStreamer (FILE *iofile, char * musiccache, int length)
|
||||
: NumChannels (0),
|
||||
SampleBits (0),
|
||||
SampleRate (0),
|
||||
File (iofile, length),
|
||||
PoolSize (0),
|
||||
PoolUsed (0),
|
||||
PoolPos (0)
|
||||
{
|
||||
StartPos = File.Tell();
|
||||
EndPos = StartPos + File.GetLength();
|
||||
if (iofile != NULL)
|
||||
{
|
||||
File = new FileReader (iofile, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
File = new MemoryReader(musiccache, length);
|
||||
}
|
||||
|
||||
StartPos = File->Tell();
|
||||
EndPos = StartPos + File->GetLength();
|
||||
init ();
|
||||
process_until_end_of_metadata ();
|
||||
}
|
||||
|
@ -129,7 +137,8 @@ FLACSong::FLACStreamer::~FLACStreamer ()
|
|||
delete[] SamplePool[0];
|
||||
SamplePool[0] = NULL;
|
||||
}
|
||||
fclose (File.GetFile());
|
||||
if (File->GetFile()!=NULL) fclose (File->GetFile());
|
||||
delete File;
|
||||
}
|
||||
|
||||
bool FLACSong::FLACStreamer::ServiceStream (void *buff1, int len, bool loop)
|
||||
|
@ -172,7 +181,7 @@ bool FLACSong::FLACStreamer::ServiceStream (void *buff1, int len, bool loop)
|
|||
{
|
||||
return FALSE;
|
||||
}
|
||||
File.Seek (StartPos, SEEK_SET);
|
||||
File->Seek (StartPos, SEEK_SET);
|
||||
reset ();
|
||||
}
|
||||
|
||||
|
@ -237,7 +246,7 @@ void FLACSong::FLACStreamer::CopyToStream (void *&sbuff, FLAC__int32 **buffer, s
|
|||
{
|
||||
if (*bytes > 0)
|
||||
{
|
||||
long here = File.Tell();
|
||||
long here = File->Tell();
|
||||
if (here == EndPos)
|
||||
{
|
||||
return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
|
||||
|
@ -248,7 +257,7 @@ void FLACSong::FLACStreamer::CopyToStream (void *&sbuff, FLAC__int32 **buffer, s
|
|||
{
|
||||
*bytes = EndPos - here;
|
||||
}
|
||||
File.Read (buffer, *bytes);
|
||||
File->Read (buffer, *bytes);
|
||||
return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ extern UINT mididevice;
|
|||
static BYTE EventLengths[7] = { 2, 2, 2, 2, 1, 1, 2 };
|
||||
static BYTE CommonLengths[15] = { 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
MIDISong2::MIDISong2 (FILE *file, int len)
|
||||
MIDISong2::MIDISong2 (FILE *file, char * musiccache, int len)
|
||||
: MidiOut (0), PlayerThread (0),
|
||||
PauseEvent (0), ExitEvent (0), VolumeChangeEvent (0),
|
||||
MusHeader (0)
|
||||
|
@ -42,8 +42,15 @@ MIDISong2::MIDISong2 (FILE *file, int len)
|
|||
int i;
|
||||
|
||||
MusHeader = new BYTE[len];
|
||||
if (fread (MusHeader, 1, len, file) != (size_t)len)
|
||||
return;
|
||||
if (file != NULL)
|
||||
{
|
||||
if (fread (MusHeader, 1, len, file) != (size_t)len)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(MusHeader, musiccache, len);
|
||||
}
|
||||
|
||||
// Do some validation of the MIDI file
|
||||
if (MusHeader[4] != 0 || MusHeader[5] != 0 || MusHeader[6] != 0 || MusHeader[7] != 6)
|
||||
|
|
|
@ -160,7 +160,7 @@ TimiditySong::~TimiditySong ()
|
|||
#endif
|
||||
}
|
||||
|
||||
TimiditySong::TimiditySong (FILE *file, int len)
|
||||
TimiditySong::TimiditySong (FILE *file, char * musiccache, int len)
|
||||
: DiskName ("zmid"),
|
||||
#ifdef _WIN32
|
||||
ReadWavePipe (INVALID_HANDLE_VALUE), WriteWavePipe (INVALID_HANDLE_VALUE),
|
||||
|
@ -191,8 +191,15 @@ TimiditySong::TimiditySong (FILE *file, int len)
|
|||
return;
|
||||
}
|
||||
|
||||
BYTE *buf = new BYTE[len];
|
||||
fread (buf, 1, len, file);
|
||||
BYTE *buf;
|
||||
|
||||
if (file!=NULL)
|
||||
{
|
||||
buf = new BYTE[len];
|
||||
fread (buf, 1, len, file);
|
||||
}
|
||||
else buf = (BYTE*)musiccache;
|
||||
|
||||
|
||||
// The file type has already been checked before this class instance was
|
||||
// created, so we only need to check one character to determine if this
|
||||
|
@ -205,8 +212,11 @@ TimiditySong::TimiditySong (FILE *file, int len)
|
|||
{
|
||||
success = ProduceMIDI (buf, f);
|
||||
}
|
||||
fclose (f);
|
||||
delete[] buf;
|
||||
if (file!=NULL)
|
||||
{
|
||||
fclose (f);
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
|
|
|
@ -57,9 +57,9 @@ MODSong::~MODSong ()
|
|||
}
|
||||
}
|
||||
|
||||
MODSong::MODSong (const char *file, int offset, int length)
|
||||
MODSong::MODSong (const char *file_or_data, int offset, int length)
|
||||
{
|
||||
m_Module = GSnd->OpenModule (file, offset, length);
|
||||
m_Module = GSnd->OpenModule (file_or_data, offset, length);
|
||||
}
|
||||
|
||||
bool MODSong::IsPlaying ()
|
||||
|
|
|
@ -28,14 +28,22 @@ static const BYTE CtrlTranslate[15] =
|
|||
121, // reset all controllers
|
||||
};
|
||||
|
||||
MUSSong2::MUSSong2 (FILE *file, int len)
|
||||
MUSSong2::MUSSong2 (FILE *file, char * musiccache, int len)
|
||||
: MidiOut (0), PlayerThread (0),
|
||||
PauseEvent (0), ExitEvent (0), VolumeChangeEvent (0),
|
||||
MusBuffer (0), MusHeader (0)
|
||||
{
|
||||
MusHeader = (MUSHeader *)new BYTE[len];
|
||||
if (fread (MusHeader, 1, len, file) != (size_t)len)
|
||||
return;
|
||||
|
||||
if (file != NULL)
|
||||
{
|
||||
if (fread (MusHeader, 1, len, file) != (size_t)len)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(MusHeader, musiccache, len);
|
||||
}
|
||||
|
||||
// Do some validation of the MUS file
|
||||
if (MusHeader->Magic != MAKE_ID('M','U','S','\x1a'))
|
||||
|
|
|
@ -21,12 +21,12 @@ CUSTOM_CVAR (Bool, opl_onechip, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
|||
}
|
||||
|
||||
|
||||
OPLMUSSong::OPLMUSSong (FILE *file, int len)
|
||||
OPLMUSSong::OPLMUSSong (FILE *file, char * musiccache, int len)
|
||||
{
|
||||
int rate = *opl_frequency;
|
||||
int samples = rate/14;
|
||||
|
||||
Music = new OPLmusicBlock (file, len, rate, samples);
|
||||
Music = new OPLmusicBlock (file, musiccache, len, rate, samples);
|
||||
|
||||
m_Stream = GSnd->CreateStream (FillStream, samples*2,
|
||||
SoundStream::Mono, rate, this);
|
||||
|
|
|
@ -46,15 +46,19 @@ CUSTOM_CVAR (Int, spc_frequency, 32000, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
|||
}
|
||||
}
|
||||
|
||||
SPCSong::SPCSong (FILE *iofile, int len)
|
||||
SPCSong::SPCSong (FILE *iofile, char * musiccache, int len)
|
||||
{
|
||||
FileReader file (iofile, len);
|
||||
|
||||
if (!LoadEmu ())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FileReader * file;
|
||||
|
||||
if (iofile != NULL) file = new FileReader(iofile, len);
|
||||
else file = new MemoryReader(musiccache, len);
|
||||
|
||||
// No sense in using a higher frequency than the final output
|
||||
int freq = MIN (*spc_frequency, *snd_samplerate);
|
||||
|
||||
|
@ -69,6 +73,7 @@ SPCSong::SPCSong (FILE *iofile, int len)
|
|||
{
|
||||
Printf (PRINT_BOLD, "Could not create music stream.\n");
|
||||
CloseEmu ();
|
||||
delete file;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -78,7 +83,7 @@ SPCSong::SPCSong (FILE *iofile, int len)
|
|||
|
||||
BYTE spcfile[66048];
|
||||
|
||||
file.Read (spcfile, 66048);
|
||||
file->Read (spcfile, 66048);
|
||||
|
||||
if (LoadSPCFile != NULL)
|
||||
{
|
||||
|
@ -104,19 +109,19 @@ SPCSong::SPCSong (FILE *iofile, int len)
|
|||
{
|
||||
DWORD id;
|
||||
|
||||
file.Read (&id, 4);
|
||||
file->Read (&id, 4);
|
||||
if (id == MAKE_ID('x','i','d','6'))
|
||||
{
|
||||
DWORD size;
|
||||
|
||||
file >> size;
|
||||
(*file) >> size;
|
||||
DWORD pos = 66056;
|
||||
|
||||
while (pos < size)
|
||||
{
|
||||
XID6Tag tag;
|
||||
|
||||
file.Read (&tag, 4);
|
||||
file->Read (&tag, 4);
|
||||
if (tag.Type == 0)
|
||||
{
|
||||
// Don't care about these
|
||||
|
@ -128,7 +133,7 @@ SPCSong::SPCSong (FILE *iofile, int len)
|
|||
if (tag.Type == 4 && tag.ID == 0x36)
|
||||
{
|
||||
DWORD amp;
|
||||
file >> amp;
|
||||
(*file) >> amp;
|
||||
if (APUVersion < 98)
|
||||
{
|
||||
amp >>= 12;
|
||||
|
@ -137,11 +142,12 @@ SPCSong::SPCSong (FILE *iofile, int len)
|
|||
break;
|
||||
}
|
||||
}
|
||||
file.Seek (LittleShort(tag.Value), SEEK_CUR);
|
||||
file->Seek (LittleShort(tag.Value), SEEK_CUR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delete file;
|
||||
}
|
||||
|
||||
SPCSong::~SPCSong ()
|
||||
|
|
|
@ -54,9 +54,9 @@ StreamSong::~StreamSong ()
|
|||
}
|
||||
}
|
||||
|
||||
StreamSong::StreamSong (const char *filename, int offset, int len)
|
||||
StreamSong::StreamSong (const char *filename_or_data, int offset, int len)
|
||||
{
|
||||
m_Stream = GSnd->OpenStream (filename, SoundStream::Loop, offset, len);
|
||||
m_Stream = GSnd->OpenStream (filename_or_data, SoundStream::Loop, offset, len);
|
||||
}
|
||||
|
||||
bool StreamSong::IsPlaying ()
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <FLAC++/decoder.h>
|
||||
#include "s_sound.h"
|
||||
#include "files.h"
|
||||
#include "w_wad.h"
|
||||
|
||||
class FLACSampleLoader : protected FLAC::Decoder::Stream
|
||||
{
|
||||
|
@ -23,7 +24,7 @@ protected:
|
|||
|
||||
void CopyToSample (size_t ofs, FLAC__int32 **buffer, size_t samples);
|
||||
|
||||
FileReader File;
|
||||
FWadLump File;
|
||||
long StartPos, EndPos;
|
||||
|
||||
void *SBuff, *SBuff2;
|
||||
|
|
|
@ -1271,6 +1271,32 @@ const char *FWadCollection::GetWadFullName (int wadnum) const
|
|||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// IsUncompressedFile
|
||||
//
|
||||
// Returns true when the lump is available as an uncompressed portion of
|
||||
// a file. The music player can play such lumps by streaming but anything
|
||||
// else has to be loaded into memory first.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FWadCollection::IsUncompressedFile(int lump) const
|
||||
{
|
||||
/*
|
||||
if ((unsigned)lump >= (unsigned)NumLumps)
|
||||
{
|
||||
I_Error ("IsUncompressedFile: %u >= NumLumps",lump);
|
||||
}
|
||||
|
||||
LumpRecord * l = &LumpInfo[lump];
|
||||
|
||||
if (l->flags & LUMPF_COMPRESSED) return false;
|
||||
else if (Wads[l->wadnum]->MemoryData!=NULL) return false;
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// W_SkinHack
|
||||
|
|
|
@ -30,10 +30,12 @@
|
|||
#define IWAD_ID (('I'<<24)|('W'<<16)|('A'<<8)|('D'))
|
||||
#define PWAD_ID (('P'<<24)|('W'<<16)|('A'<<8)|('D'))
|
||||
#define RFF_ID (('R'<<24)|('F'<<16)|('F'<<8)|(0x1a))
|
||||
#define ZIP_ID (('P'<<24)|('K'<<16)|(3<<8)|(4))
|
||||
#else
|
||||
#define IWAD_ID (('I')|('W'<<8)|('A'<<16)|('D'<<24))
|
||||
#define PWAD_ID (('P')|('W'<<8)|('A'<<16)|('D'<<24))
|
||||
#define RFF_ID (('R')|('F'<<8)|('F'<<16)|(0x1a<<24))
|
||||
#define ZIP_ID (('P')|('K'<<8)|(3<<16)|(4<<24))
|
||||
#endif
|
||||
|
||||
// [RH] Remove limit on number of WAD files
|
||||
|
@ -167,6 +169,7 @@ public:
|
|||
int GetLumpNamespace (int lump) const; // [RH] Returns the namespace a lump belongs to
|
||||
bool CheckLumpName (int lump, const char *name) const; // [RH] Returns true if the names match
|
||||
|
||||
bool IsUncompressedFile(int lump) const;
|
||||
int GetNumLumps () const;
|
||||
|
||||
protected:
|
||||
|
|
Loading…
Reference in a new issue