summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTim Angus <tim@ngus.net>2009-10-30 20:46:35 +0000
committerTim Angus <tim@ngus.net>2013-01-03 00:17:16 +0000
commiteccd3e0b530e2b66e564770432c8f455444e4e95 (patch)
treed1f4611670e696f9c49fa7396bf998a1c1becd99 /src
parent8b14cc907dc8253174bf27a67ba1ee5b6b4e5fe5 (diff)
* Merge ioq3-r1715
Diffstat (limited to 'src')
-rw-r--r--src/client/snd_openal.c405
-rwxr-xr-xsrc/libs/macosx/libSDL-1.2.0.dylibbin4474044 -> 4436304 bytes
-rw-r--r--src/qcommon/vm_x86_64.c254
-rw-r--r--src/sys/sys_win32.c3
4 files changed, 283 insertions, 379 deletions
diff --git a/src/client/snd_openal.c b/src/client/snd_openal.c
index 7ba9c9a3..96068075 100644
--- a/src/client/snd_openal.c
+++ b/src/client/snd_openal.c
@@ -111,8 +111,10 @@ static void S_AL_ClearError( qboolean quiet )
if( quiet )
return;
if(error != AL_NO_ERROR)
+ {
Com_Printf(S_COLOR_YELLOW "WARNING: unhandled AL error: %s\n",
S_AL_ErrorMsg(error));
+ }
}
@@ -527,6 +529,7 @@ typedef struct src_s
float lastTimePos; // On stopped loops, the last position in the buffer
int lastSampleTime; // Time when this was stopped
+ vec3_t loopSpeakerPos; // Origin of the loop speaker
qboolean local; // Is this local (relative to the cam)
} src_t;
@@ -538,6 +541,7 @@ typedef struct src_s
#endif
static src_t srcList[MAX_SRC];
static int srcCount = 0;
+static int srcActiveCnt = 0;
static qboolean alSourcesInitialised = qfalse;
static vec3_t lastListenerOrigin = { 0.0f, 0.0f, 0.0f };
@@ -605,8 +609,6 @@ static void S_AL_ScaleGain(src_t *chksrc, vec3_t origin)
if(chksrc->scaleGain != scaleFactor);
{
chksrc->scaleGain = scaleFactor;
- // if(scaleFactor > 0.0f)
- // Com_Printf("%f\n", scaleFactor);
qalSourcef(chksrc->alSource, AL_GAIN, chksrc->scaleGain);
}
}
@@ -662,6 +664,7 @@ qboolean S_AL_SrcInit( void )
// Clear the sources data structure
memset(srcList, 0, sizeof(srcList));
srcCount = 0;
+ srcActiveCnt = 0;
// Cap s_alSources to MAX_SRC
limit = s_alSources->integer;
@@ -695,6 +698,7 @@ static
void S_AL_SrcShutdown( void )
{
int i;
+ src_t *curSource;
if(!alSourcesInitialised)
return;
@@ -702,9 +706,14 @@ void S_AL_SrcShutdown( void )
// Destroy all the sources
for(i = 0; i < srcCount; i++)
{
- if(srcList[i].isLocked)
+ curSource = &srcList[i];
+
+ if(curSource->isLocked)
Com_DPrintf( S_COLOR_YELLOW "WARNING: Source %d is locked\n", i);
+ if(curSource->entity > 0)
+ entityList[curSource->entity].srcAllocated = qfalse;
+
qalSourceStop(srcList[i].alSource);
qalDeleteSources(1, &srcList[i].alSource);
}
@@ -737,7 +746,6 @@ static void S_AL_SrcSetup(srcHandle_t src, sfxHandle_t sfx, alSrcPriority_t prio
curSource->priority = priority;
curSource->entity = entity;
curSource->channel = channel;
- curSource->isActive = qtrue;
curSource->isPlaying = qfalse;
curSource->isLocked = qfalse;
curSource->isLooping = qfalse;
@@ -774,6 +782,36 @@ Remove given source as loop master if it is the master and hand off master statu
=================
*/
+static void S_AL_SaveLoopPos(src_t *dest, ALuint alSource)
+{
+ int error;
+
+ S_AL_ClearError(qfalse);
+
+ qalGetSourcef(alSource, AL_SEC_OFFSET, &dest->lastTimePos);
+ if((error = qalGetError()) != AL_NO_ERROR)
+ {
+ // Old OpenAL implementations don't support AL_SEC_OFFSET
+
+ if(error != AL_INVALID_ENUM)
+ {
+ Com_Printf(S_COLOR_YELLOW "WARNING: Could not get time offset for alSource %d: %s\n",
+ alSource, S_AL_ErrorMsg(error));
+ }
+
+ dest->lastTimePos = -1;
+ }
+ else
+ dest->lastSampleTime = Sys_Milliseconds();
+}
+
+/*
+=================
+S_AL_NewLoopMaster
+Remove given source as loop master if it is the master and hand off master status to another source in this case.
+=================
+*/
+
static void S_AL_NewLoopMaster(src_t *rmSource, qboolean iskilled)
{
int index;
@@ -789,7 +827,16 @@ static void S_AL_NewLoopMaster(src_t *rmSource, qboolean iskilled)
if(curSfx->loopCnt)
{
- if(rmSource == &srcList[curSfx->masterLoopSrc])
+ if(rmSource->priority == SRCPRI_ENTITY)
+ {
+ if(!iskilled && rmSource->isPlaying)
+ {
+ // only sync ambient loops...
+ // It makes more sense to have sounds for weapons/projectiles unsynced
+ S_AL_SaveLoopPos(rmSource, rmSource->alSource);
+ }
+ }
+ else if(rmSource == &srcList[curSfx->masterLoopSrc])
{
int firstInactive = -1;
@@ -803,7 +850,7 @@ static void S_AL_NewLoopMaster(src_t *rmSource, qboolean iskilled)
curSource = &srcList[index];
if(curSource->sfx == rmSource->sfx && curSource != rmSource &&
- curSource->isActive && curSource->isLooping)
+ curSource->isActive && curSource->isLooping && curSource->priority == SRCPRI_AMBIENT)
{
if(curSource->isPlaying)
{
@@ -819,15 +866,22 @@ static void S_AL_NewLoopMaster(src_t *rmSource, qboolean iskilled)
if(!curSfx->loopActiveCnt)
{
if(firstInactive < 0)
- curSource = rmSource;
+ {
+ if(iskilled)
+ {
+ curSfx->masterLoopSrc = -1;
+ return;
+ }
+ else
+ curSource = rmSource;
+ }
else
curSource = &srcList[firstInactive];
if(rmSource->isPlaying)
{
// this was the last not stopped source, save last sample position + time
- qalGetSourcef(rmSource->alSource, AL_SEC_OFFSET, &curSource->lastTimePos);
- curSource->lastSampleTime = Sys_Milliseconds();
+ S_AL_SaveLoopPos(curSource, rmSource->alSource);
}
else
{
@@ -890,7 +944,11 @@ static void S_AL_SrcKill(srcHandle_t src)
curSource->priority = 0;
curSource->entity = -1;
curSource->channel = -1;
- curSource->isActive = qfalse;
+ if(curSource->isActive)
+ {
+ curSource->isActive = qfalse;
+ srcActiveCnt--;
+ }
curSource->isLocked = qfalse;
curSource->isTracking = qfalse;
curSource->local = qfalse;
@@ -909,24 +967,55 @@ srcHandle_t S_AL_SrcAlloc( alSrcPriority_t priority, int entnum, int channel )
int weakest = -1;
int weakest_time = Sys_Milliseconds();
int weakest_pri = 999;
+ float weakest_gain = 1000.0;
+ qboolean weakest_isplaying = qtrue;
+ int weakest_numloops = 0;
+ src_t *curSource;
for(i = 0; i < srcCount; i++)
{
+ curSource = &srcList[i];
+
// If it's locked, we aren't even going to look at it
- if(srcList[i].isLocked)
+ if(curSource->isLocked)
continue;
// Is it empty or not?
- if((!srcList[i].isActive) && (empty == -1))
+ if(!curSource->isActive)
+ {
empty = i;
- else if(srcList[i].priority < priority)
+ break;
+ }
+
+ if(curSource->isPlaying)
{
- // If it's older or has lower priority, flag it as weak
- if((srcList[i].priority < weakest_pri) ||
- (srcList[i].lastUsedTime < weakest_time))
+ if(weakest_isplaying && curSource->priority < priority &&
+ (curSource->priority < weakest_pri ||
+ (!curSource->isLooping && (curSource->scaleGain < weakest_gain || curSource->lastUsedTime < weakest_time))))
{
- weakest_pri = srcList[i].priority;
- weakest_time = srcList[i].lastUsedTime;
+ // If it has lower priority, is fainter or older, flag it as weak
+ // the last two values are only compared if it's not a looping sound, because we want to prevent two
+ // loops (loops are added EVERY frame) fighting for a slot
+ weakest_pri = curSource->priority;
+ weakest_time = curSource->lastUsedTime;
+ weakest_gain = curSource->scaleGain;
+ weakest = i;
+ }
+ }
+ else
+ {
+ weakest_isplaying = qfalse;
+
+ if(weakest < 0 ||
+ knownSfx[curSource->sfx].loopCnt > weakest_numloops ||
+ curSource->priority < weakest_pri ||
+ curSource->lastUsedTime < weakest_time)
+ {
+ // Sources currently not playing of course have lowest priority
+ // also try to always keep at least one loop master for every loop sound
+ weakest_pri = curSource->priority;
+ weakest_time = curSource->lastUsedTime;
+ weakest_numloops = knownSfx[curSource->sfx].loopCnt;
weakest = i;
}
}
@@ -936,7 +1025,7 @@ srcHandle_t S_AL_SrcAlloc( alSrcPriority_t priority, int entnum, int channel )
// causes incorrect behaviour versus defacto baseq3
#if 0
// Is it an exact match, and not on channel 0?
- if((srcList[i].entity == entnum) && (srcList[i].channel == channel) && (channel != 0))
+ if((curSource->entity == entnum) && (curSource->channel == channel) && (channel != 0))
{
S_AL_SrcKill(i);
return i;
@@ -944,22 +1033,17 @@ srcHandle_t S_AL_SrcAlloc( alSrcPriority_t priority, int entnum, int channel )
#endif
}
- // Do we have an empty one?
- if(empty != -1)
- {
- S_AL_SrcKill( empty );
- return empty;
- }
-
- // No. How about an overridable one?
- if(weakest != -1)
+ if(empty == -1)
+ empty = weakest;
+
+ if(empty >= 0)
{
- S_AL_SrcKill(weakest);
- return weakest;
+ S_AL_SrcKill(empty);
+ srcList[empty].isActive = qtrue;
+ srcActiveCnt++;
}
- // Nothing. Return failure (cries...)
- return -1;
+ return empty;
}
/*
@@ -1039,7 +1123,7 @@ Necessary for i.g. Western Quake3 mod which is buggy.
static qboolean S_AL_CheckInput(int entityNum, sfxHandle_t sfx)
{
if (entityNum < 0 || entityNum > MAX_GENTITIES)
- Com_Error(ERR_DROP, "S_StartSound: bad entitynum %i", entityNum);
+ Com_Error(ERR_DROP, "ERROR: S_AL_CheckInput: bad entitynum %i", entityNum);
if (sfx < 0 || sfx >= numSfx)
{
@@ -1086,49 +1170,61 @@ S_AL_StartSound
Play a one-shot sound effect
=================
*/
-static
-void S_AL_StartSound( vec3_t origin, int entnum, int entchannel, sfxHandle_t sfx )
+static void S_AL_StartSound( vec3_t origin, int entnum, int entchannel, sfxHandle_t sfx )
{
vec3_t sorigin;
srcHandle_t src;
+ src_t *curSource;
- if(S_AL_CheckInput(origin ? 0 : entnum, sfx))
+ if(origin)
+ {
+ if(S_AL_CheckInput(0, sfx))
+ return;
+
+ VectorCopy(origin, sorigin);
+ }
+ else
+ {
+ if(S_AL_CheckInput(entnum, sfx))
+ return;
+
+ if(S_AL_HearingThroughEntity(entnum))
+ {
+ S_AL_StartLocalSound(sfx, entchannel);
+ return;
+ }
+
+ VectorCopy(entityList[entnum].origin, sorigin);
+ }
+
+ S_AL_SanitiseVector(sorigin);
+
+ if((srcActiveCnt > 5 * srcCount / 3) &&
+ (DistanceSquared(sorigin, lastListenerOrigin) >=
+ (s_alMaxDistance->value + s_alGraceDistance->value) * (s_alMaxDistance->value + s_alGraceDistance->value)))
+ {
+ // We're getting tight on sources and source is not within hearing distance so don't add it
return;
+ }
// Try to grab a source
src = S_AL_SrcAlloc(SRCPRI_ONESHOT, entnum, entchannel);
if(src == -1)
return;
- // Set up the effect
- if( origin == NULL )
- {
- if( S_AL_HearingThroughEntity( entnum ) )
- {
- // Where the entity is the local player, play a local sound
- S_AL_SrcSetup( src, sfx, SRCPRI_ONESHOT, entnum, entchannel, qtrue );
- VectorClear( sorigin );
- }
- else
- {
- S_AL_SrcSetup( src, sfx, SRCPRI_ONESHOT, entnum, entchannel, qfalse );
- VectorCopy( entityList[ entnum ].origin, sorigin );
- }
- srcList[ src ].isTracking = qtrue;
- }
- else
- {
- S_AL_SrcSetup( src, sfx, SRCPRI_ONESHOT, entnum, entchannel, qfalse );
- VectorCopy( origin, sorigin );
- }
+ S_AL_SrcSetup(src, sfx, SRCPRI_ONESHOT, entnum, entchannel, qfalse);
+
+ curSource = &srcList[src];
- S_AL_SanitiseVector( sorigin );
- qalSourcefv( srcList[ src ].alSource, AL_POSITION, sorigin );
- S_AL_ScaleGain(&srcList[src], sorigin);
+ if(!origin)
+ curSource->isTracking = qtrue;
+
+ qalSourcefv(curSource->alSource, AL_POSITION, sorigin );
+ S_AL_ScaleGain(curSource, sorigin);
// Start it playing
- srcList[src].isPlaying = qtrue;
- qalSourcePlay(srcList[src].alSource);
+ curSource->isPlaying = qtrue;
+ qalSourcePlay(curSource->alSource);
}
/*
@@ -1158,6 +1254,10 @@ static void S_AL_SrcLoop( alSrcPriority_t priority, sfxHandle_t sfx,
int src;
sentity_t *sent = &entityList[ entityNum ];
src_t *curSource;
+ vec3_t sorigin, svelocity;
+
+ if(S_AL_CheckInput(entityNum, sfx))
+ return;
// Do we need to allocate a new source for this entity
if( !sent->srcAllocated )
@@ -1171,10 +1271,18 @@ static void S_AL_SrcLoop( alSrcPriority_t priority, sfxHandle_t sfx,
return;
}
+ curSource = &srcList[src];
+
sent->startLoopingSound = qtrue;
+
+ curSource->lastTimePos = -1.0;
+ curSource->lastSampleTime = Sys_Milliseconds();
}
else
+ {
src = sent->srcIndex;
+ curSource = &srcList[src];
+ }
sent->srcAllocated = qtrue;
sent->srcIndex = src;
@@ -1185,33 +1293,46 @@ static void S_AL_SrcLoop( alSrcPriority_t priority, sfxHandle_t sfx,
// If this is not set then the looping sound is stopped.
sent->loopAddedThisFrame = qtrue;
- curSource = &srcList[src];
-
// UGH
// These lines should be called via S_AL_SrcSetup, but we
// can't call that yet as it buffers sfxes that may change
// with subsequent calls to S_AL_SrcLoop
curSource->entity = entityNum;
curSource->isLooping = qtrue;
- curSource->isActive = qtrue;
if( S_AL_HearingThroughEntity( entityNum ) )
{
curSource->local = qtrue;
- qalSourcefv( curSource->alSource, AL_POSITION, vec3_origin );
- qalSourcefv( curSource->alSource, AL_VELOCITY, vec3_origin );
+ VectorClear(sorigin);
+
+ qalSourcefv(curSource->alSource, AL_POSITION, sorigin);
+ qalSourcefv(curSource->alSource, AL_VELOCITY, sorigin);
}
else
{
curSource->local = qfalse;
- qalSourcefv( curSource->alSource, AL_POSITION, (ALfloat *)sent->origin );
- qalSourcefv( curSource->alSource, AL_VELOCITY, (ALfloat *)velocity );
+ if(origin)
+ VectorCopy(origin, sorigin);
+ else
+ VectorCopy(sent->origin, sorigin);
+
+ S_AL_SanitiseVector(sorigin);
- }
+ VectorCopy(sorigin, curSource->loopSpeakerPos);
+
+ if(velocity)
+ {
+ VectorCopy(velocity, svelocity);
+ S_AL_SanitiseVector(svelocity);
+ }
+ else
+ VectorClear(svelocity);
- S_AL_ScaleGain(curSource, sent->origin);
+ qalSourcefv( curSource->alSource, AL_POSITION, (ALfloat *)sorigin );
+ qalSourcefv( curSource->alSource, AL_VELOCITY, (ALfloat *)velocity );
+ }
}
/*
@@ -1219,20 +1340,9 @@ static void S_AL_SrcLoop( alSrcPriority_t priority, sfxHandle_t sfx,
S_AL_AddLoopingSound
=================
*/
-static
-void S_AL_AddLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx )
+static void S_AL_AddLoopingSound(int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx)
{
- vec3_t sanOrigin, sanVelocity;
-
- if(S_AL_CheckInput(entityNum, sfx))
- return;
-
- VectorCopy( origin, sanOrigin );
- VectorCopy( velocity, sanVelocity );
- S_AL_SanitiseVector( sanOrigin );
- S_AL_SanitiseVector( sanVelocity );
-
- S_AL_SrcLoop(SRCPRI_ENTITY, sfx, sanOrigin, sanVelocity, entityNum);
+ S_AL_SrcLoop(SRCPRI_ENTITY, sfx, origin, velocity, entityNum);
}
/*
@@ -1240,27 +1350,9 @@ void S_AL_AddLoopingSound( int entityNum, const vec3_t origin, const vec3_t velo
S_AL_AddRealLoopingSound
=================
*/
-static
-void S_AL_AddRealLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx )
+static void S_AL_AddRealLoopingSound(int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx)
{
- vec3_t sanOrigin, sanVelocity;
-
- if(S_AL_CheckInput(entityNum, sfx))
- return;
-
- VectorCopy( origin, sanOrigin );
- VectorCopy( velocity, sanVelocity );
- S_AL_SanitiseVector( sanOrigin );
- S_AL_SanitiseVector( sanVelocity );
-
- // There are certain maps (*cough* Q3:TA mpterra*) that have large quantities
- // of ET_SPEAKERS in the PVS at any given time. OpenAL can't cope with mixing
- // large numbers of sounds, so this culls them by distance
- if( DistanceSquared( sanOrigin, lastListenerOrigin ) > (s_alMaxDistance->value + s_alGraceDistance->value) *
- (s_alMaxDistance->value + s_alGraceDistance->value) )
- return;
-
- S_AL_SrcLoop(SRCPRI_AMBIENT, sfx, sanOrigin, sanVelocity, entityNum);
+ S_AL_SrcLoop(SRCPRI_AMBIENT, sfx, origin, velocity, entityNum);
}
/*
@@ -1288,8 +1380,8 @@ void S_AL_SrcUpdate( void )
int i;
int entityNum;
ALint state;
- src_t *curSource;
-
+ src_t *curSource;
+
for(i = 0; i < srcCount; i++)
{
entityNum = srcList[i].entity;
@@ -1313,9 +1405,11 @@ void S_AL_SrcUpdate( void )
{
sentity_t *sent = &entityList[ entityNum ];
- // If a looping effect hasn't been touched this frame, pause it
+ // If a looping effect hasn't been touched this frame, pause or kill it
if(sent->loopAddedThisFrame)
{
+ alSfx_t *curSfx;
+
// The sound has changed without an intervening removal
if(curSource->isActive && !sent->startLoopingSound &&
curSource->sfx != sent->loopSfx)
@@ -1339,39 +1433,81 @@ void S_AL_SrcUpdate( void )
sent->startLoopingSound = qfalse;
}
+ curSfx = &knownSfx[curSource->sfx];
+
+ S_AL_ScaleGain(curSource, curSource->loopSpeakerPos);
+ if(!curSource->scaleGain)
+ {
+ if(curSource->isPlaying)
+ {
+ // Sound is mute, stop playback until we are in range again
+ S_AL_NewLoopMaster(curSource, qfalse);
+ qalSourceStop(curSource->alSource);
+ curSource->isPlaying = qfalse;
+ }
+ else if(!curSfx->loopActiveCnt && curSfx->masterLoopSrc < 0)
+ curSfx->masterLoopSrc = i;
+
+ continue;
+ }
+
if(!curSource->isPlaying)
{
- alSfx_t *curSfx = &knownSfx[curSource->sfx];
+ if(curSource->priority == SRCPRI_AMBIENT)
+ {
+ // If there are other ambient looping sources with the same sound,
+ // make sure the sound of these sources are in sync.
- // If there are other looping sources with the same sound,
- // make sure the sound of these sources are in sync.
+ if(curSfx->loopActiveCnt)
+ {
+ int offset, error;
- if(curSfx->loopActiveCnt)
- {
- int offset;
+ // we already have a master loop playing, get buffer position.
+ S_AL_ClearError(qfalse);
+ qalGetSourcei(srcList[curSfx->masterLoopSrc].alSource, AL_SAMPLE_OFFSET, &offset);
+ if((error = qalGetError()) != AL_NO_ERROR)
+ {
+ if(error != AL_INVALID_ENUM)
+ {
+ Com_Printf(S_COLOR_YELLOW "WARNING: Cannot get sample offset from source %d: "
+ "%s\n", i, S_AL_ErrorMsg(error));
+ }
+ }
+ else
+ qalSourcei(curSource->alSource, AL_SAMPLE_OFFSET, offset);
+ }
+ else if(curSfx->loopCnt && curSfx->masterLoopSrc >= 0)
+ {
+ float secofs;
+
+ src_t *master = &srcList[curSfx->masterLoopSrc];
+ // This loop sound used to be played, but all sources are stopped. Use last sample position/time
+ // to calculate offset so the player thinks the sources continued playing while they were inaudible.
- // we already have a master loop playing, get buffer position.
- qalGetSourcei(srcList[curSfx->masterLoopSrc].alSource, AL_SAMPLE_OFFSET, &offset);
- qalSourcei(curSource->alSource, AL_SAMPLE_OFFSET, offset);
+ if(master->lastTimePos >= 0)
+ {
+ secofs = master->lastTimePos + (Sys_Milliseconds() - master->lastSampleTime) / 1000.0f;
+ secofs = fmodf(secofs, (float) curSfx->info.samples / curSfx->info.rate);
+
+ qalSourcef(curSource->alSource, AL_SEC_OFFSET, secofs);
+ }
+
+ // I be the master now
+ curSfx->masterLoopSrc = i;
+ }
+ else
+ curSfx->masterLoopSrc = i;
}
- else if(curSfx->loopCnt && curSfx->masterLoopSrc >= 0)
+ else if(curSource->lastTimePos >= 0)
{
float secofs;
- src_t *master = &srcList[curSfx->masterLoopSrc];
- // This loop sound used to be played, but all sources are stopped. Use last sample position/time
- // to calculate offset so the player thinks the sources continued playing while they were inaudible.
-
- secofs = master->lastTimePos + (Sys_Milliseconds() - master->lastSampleTime) / 1000.0f;
- secofs = fmodf(secofs, curSfx->info.samples / curSfx->info.rate);
+ // For unsynced loops (SRCPRI_ENTITY) just carry on playing as if the sound was never stopped
+ secofs = curSource->lastTimePos + (Sys_Milliseconds() - curSource->lastSampleTime) / 1000.0f;
+ secofs = fmodf(secofs, (float) curSfx->info.samples / curSfx->info.rate);
qalSourcef(curSource->alSource, AL_SEC_OFFSET, secofs);
-
- // I be the master now
- curSfx->masterLoopSrc = i;
}
- else
- curSfx->masterLoopSrc = i;
curSfx->loopActiveCnt++;
@@ -1393,12 +1529,17 @@ void S_AL_SrcUpdate( void )
}
}
- else if(curSource->isPlaying)
+ else if(curSource->priority == SRCPRI_AMBIENT)
{
- S_AL_NewLoopMaster(curSource, qfalse);
- qalSourceStop(curSource->alSource);
- curSource->isPlaying = qfalse;
+ if(curSource->isPlaying)
+ {
+ S_AL_NewLoopMaster(curSource, qfalse);
+ qalSourceStop(curSource->alSource);
+ curSource->isPlaying = qfalse;
+ }
}
+ else
+ S_AL_SrcKill(i);
continue;
}
diff --git a/src/libs/macosx/libSDL-1.2.0.dylib b/src/libs/macosx/libSDL-1.2.0.dylib
index 2ea0f454..701e596f 100755
--- a/src/libs/macosx/libSDL-1.2.0.dylib
+++ b/src/libs/macosx/libSDL-1.2.0.dylib
Binary files differ
diff --git a/src/qcommon/vm_x86_64.c b/src/qcommon/vm_x86_64.c
index b424baf8..02e7bf9c 100644
--- a/src/qcommon/vm_x86_64.c
+++ b/src/qcommon/vm_x86_64.c
@@ -36,7 +36,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include <unistd.h>
#include <stdarg.h>
-//#define USE_GAS
//#define DEBUG_VM
#ifdef DEBUG_VM
@@ -48,16 +47,10 @@ static FILE* qdasmout;
#define VM_X86_64_MMAP
-#ifndef USE_GAS
void assembler_set_output(char* buf);
size_t assembler_get_code_size(void);
void assembler_init(int pass);
void assemble_line(const char* input, size_t len);
-#ifdef Dfprintf
-#undef Dfprintf
-#define Dfprintf(args...)
-#endif
-#endif // USE_GAS
static void VM_Destroy_Compiled(vm_t* self);
@@ -226,10 +219,6 @@ static unsigned char op_argsize[256] =
[OP_BLOCK_COPY] = 4,
};
-#ifdef USE_GAS
-#define emit(x...) \
- do { fprintf(fh_s, ##x); fputc('\n', fh_s); } while(0)
-#else
void emit(const char* fmt, ...)
{
va_list ap;
@@ -239,16 +228,10 @@ void emit(const char* fmt, ...)
va_end(ap);
assemble_line(line, strlen(line));
}
-#endif // USE_GAS
-#ifdef USE_GAS
-#define JMPIARG \
- emit("jmp i_%08x", iarg);
-#else
#define JMPIARG \
emit("movq $%lu, %%rax", vm->codeBase+vm->instructionPointers[iarg]); \
emit("jmpq *%%rax");
-#endif
// integer compare and jump
#define IJ(op) \
@@ -336,102 +319,8 @@ void emit(const char* fmt, ...)
static void* getentrypoint(vm_t* vm)
{
-#ifdef USE_GAS
- return vm->codeBase+64; // skip ELF header
-#else
return vm->codeBase;
-#endif // USE_GAS
-}
-
-#ifdef USE_GAS
-char* mmapfile(const char* fn, size_t* size)
-{
- int fd = -1;
- char* mem = NULL;
- struct stat stb;
-
- fd = open(fn, O_RDONLY);
- if(fd == -1)
- goto out;
-
- if(fstat(fd, &stb) == -1)
- goto out;
-
- *size = stb.st_size;
-
- mem = mmap(NULL, stb.st_size, PROT_READ|PROT_EXEC, MAP_SHARED, fd, 0);
- if(mem == (void*)-1)
- mem = NULL;
-
-out:
- if(fd != -1)
- close(fd);
-
- return mem;
-}
-
-static int doas(char* in, char* out, unsigned char** compiledcode)
-{
- unsigned char* mem;
- size_t size = -1;
- pid_t pid;
-
- Com_Printf("running assembler < %s > %s\n", in, out);
- pid = fork();
- if(pid == -1)
- {
- Com_Printf(S_COLOR_RED "can't fork\n");
- return -1;
- }
-
- if(!pid)
- {
- char* const argv[] = {
- "as",
- "-o",
- out,
- in,
- NULL
- };
-
- execvp(argv[0], argv);
- _exit(-1);
- }
- else
- {
- int status;
- if(waitpid(pid, &status, 0) == -1)
- {
- Com_Printf(S_COLOR_RED "can't wait for as: %s\n", strerror(errno));
- return -1;
- }
-
- if(!WIFEXITED(status))
- {
- Com_Printf(S_COLOR_RED "as died\n");
- return -1;
- }
- if(WEXITSTATUS(status))
- {
- Com_Printf(S_COLOR_RED "as failed with status %d\n", WEXITSTATUS(status));
- return -1;
- }
- }
-
- Com_Printf("done\n");
-
- mem = (unsigned char*)mmapfile(out, &size);
- if(!mem)
- {
- Com_Printf(S_COLOR_RED "can't mmap object file %s: %s\n", out, strerror(errno));
- return -1;
- }
-
- *compiledcode = mem;
-
- return size;
}
-#endif // USE_GAS
static void block_copy_vm(unsigned dest, unsigned src, unsigned count)
{
@@ -462,68 +351,10 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
unsigned char barg = 0;
int neednilabel = 0;
struct timeval tvstart = {0, 0};
-
-#ifdef USE_GAS
- byte* compiledcode;
- int compiledsize;
- void* entryPoint;
- char fn_s[2*MAX_QPATH]; // output file for assembler code
- char fn_o[2*MAX_QPATH]; // file written by as
#ifdef DEBUG_VM
char fn_d[MAX_QPATH]; // disassembled
#endif
- FILE* fh_s;
- int fd_s, fd_o;
-
- gettimeofday(&tvstart, NULL);
-
- Com_Printf("compiling %s\n", vm->name);
-
-#ifdef DEBUG_VM
- snprintf(fn_s, sizeof(fn_s), "%.63s.s", vm->name);
- snprintf(fn_o, sizeof(fn_o), "%.63s.o", vm->name);
- fd_s = open(fn_s, O_CREAT|O_WRONLY|O_TRUNC, 0644);
- fd_o = open(fn_o, O_CREAT|O_WRONLY|O_TRUNC, 0644);
-#else
- snprintf(fn_s, sizeof(fn_s), "/tmp/%.63s.s_XXXXXX", vm->name);
- snprintf(fn_o, sizeof(fn_o), "/tmp/%.63s.o_XXXXXX", vm->name);
- fd_s = mkstemp(fn_s);
- fd_o = mkstemp(fn_o);
-#endif
- if(fd_s == -1 || fd_o == -1)
- {
- if(fd_s != -1) close(fd_s);
- if(fd_o != -1) close(fd_o);
- unlink(fn_s);
- unlink(fn_o);
-
- Com_Printf(S_COLOR_RED "can't create temporary file %s for vm\n", fn_s);
- vm->compiled = qfalse;
- return;
- }
-
-#ifdef DEBUG_VM
- strcpy(fn_d,vm->name);
- strcat(fn_d, ".qdasm");
-
- qdasmout = fopen(fn_d, "w");
-#endif
- fh_s = fdopen(fd_s, "wb");
- if(!fh_s)
- {
- Com_Printf(S_COLOR_RED "can't write %s\n", fn_s);
- vm->compiled = qfalse;
- return;
- }
-
- emit("start:");
- emit("or %%r8, %%r8"); // check whether to set up instruction pointers
- emit("jnz main");
- emit("jmp setupinstructionpointers");
-
- emit("main:");
-#else // USE_GAS
int pass;
size_t compiledOfs = 0;
@@ -544,7 +375,12 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
assembler_init(pass);
-#endif // USE_GAS
+#ifdef DEBUG_VM
+ strcpy(fn_d,vm->name);
+ strcat(fn_d, ".qdasm");
+
+ qdasmout = fopen(fn_d, "w");
+#endif
// translate all instructions
pc = 0;
@@ -555,12 +391,10 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
op = code[ pc ];
++pc;
-#ifndef USE_GAS
vm->instructionPointers[instruction] = assembler_get_code_size();
-#endif
/* store current instruction number in r15 for debugging */
-#if 1
+#if DEBUG_VM
emit("nop");
emit("movq $%d, %%r15", instruction);
emit("nop");
@@ -582,15 +416,11 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
Dfprintf(qdasmout, "%s\n", opnames[op]);
}
-#ifdef USE_GAS
- emit("i_%08x:", instruction);
-#else
if(neednilabel)
{
emit("i_%08x:", instruction);
neednilabel = 0;
}
-#endif
switch ( op )
{
@@ -947,82 +777,20 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
}
}
-#ifdef USE_GAS
- emit("setupinstructionpointers:");
- emit("movq $%lu, %%rax", (unsigned long)vm->instructionPointers);
- for ( instruction = 0; instruction < header->instructionCount; ++instruction )
- {
- emit("movl $i_%08x-start, %d(%%rax)", instruction, instruction*4);
- }
- emit("ret");
-
- emit("debugger:");
- if(1);
- {
- int i = 6;
- while(i--)
- {
- emit("nop");
- emit("int3");
- }
- }
-
- fflush(fh_s);
- fclose(fh_s);
+ } // pass loop
- compiledsize = doas(fn_s, fn_o, &compiledcode);
- if(compiledsize == -1)
- {
- vm->compiled = qfalse;
- goto out;
- }
-
- vm->codeBase = compiledcode; // remember to skip ELF header!
- vm->codeLength = compiledsize;
-
-#else // USE_GAS
- }
assembler_init(0);
if(mprotect(vm->codeBase, compiledOfs, PROT_READ|PROT_EXEC))
Com_Error(ERR_DROP, "VM_CompileX86: mprotect failed");
-#endif // USE_GAS
vm->destroy = VM_Destroy_Compiled;
-
-#ifdef USE_GAS
- entryPoint = getentrypoint(vm);
-
-// __asm__ __volatile__ ("int3");
- Com_Printf("computing jump table\n");
-
- // call code with r8 set to zero to set up instruction pointers
- __asm__ __volatile__ (
- " xorq %%r8,%%r8 \r\n" \
- " movq %0,%%r10 \r\n" \
- " callq *%%r10 \r\n" \
- :
- : "m" (entryPoint)
- : "%r8", "%r10", "%rax"
- );
#ifdef DEBUG_VM
fflush(qdasmout);
fclose(qdasmout);
#endif
-
-out:
- close(fd_o);
-
-#ifndef DEBUG_VM
- if(!com_developer->integer)
- {
- unlink(fn_o);
- unlink(fn_s);
- }
-#endif
-#endif // USE_GAS
-
+
if(vm->compiled)
{
struct timeval tvdone = {0, 0};
@@ -1038,9 +806,7 @@ out:
void VM_Destroy_Compiled(vm_t* self)
{
-#ifdef USE_GAS
- munmap(self->codeBase, self->codeLength);
-#elif _WIN32
+#ifdef _WIN32
VirtualFree(self->codeBase, 0, MEM_RELEASE);
#else
munmap(self->codeBase, self->codeLength);
diff --git a/src/sys/sys_win32.c b/src/sys/sys_win32.c
index bf4b8f75..18efe406 100644
--- a/src/sys/sys_win32.c
+++ b/src/sys/sys_win32.c
@@ -650,8 +650,5 @@ void Sys_PlatformInit( void )
}
else
SDL_VIDEODRIVER_externallySet = qfalse;
-
- // Don't redirect to stdout.txt and stderr.txt
- _putenv( "SDL_STDIO_REDIRECT=0" );
#endif
}