ioquake3 resync to revision 3522 from 3511.

Fix axis returned by IQM's LerpTag
Calculate bounds for unanimated IQM models
Fix loading favorites as initial source in server browser
Improve finding obelisk entitynum for bot AI
Fix SDL audio playback with surround sound
Fix predicting entity origin on rotating mover
Allow binds to use hex values for all key codes
Disable pulseaudio capture regardless of SDL version
Fix SDL audio playback with 16-bit stereo sound
Make s_info command display channels instead of stereo
Fix cross-compiling using mingw-w64 on Ubuntu 18.04
This commit is contained in:
zturtleman 2018-10-16 17:48:51 +00:00
parent d0f6099cc1
commit 6bc3b33eab
11 changed files with 251 additions and 160 deletions

View file

@ -44,7 +44,7 @@ ifndef BUILD_DEFINES
endif endif
# ioquake3 svn version that this is based on # ioquake3 svn version that this is based on
IOQ3_REVISION = 3444 IOQ3_REVISION = 3522
############################################################################# #############################################################################
# #
@ -292,7 +292,17 @@ bin_path=$(shell which $(1) 2> /dev/null)
# set PKG_CONFIG_PATH or PKG_CONFIG to influence this, e.g. # set PKG_CONFIG_PATH or PKG_CONFIG to influence this, e.g.
# PKG_CONFIG_PATH=/opt/cross/i386-mingw32msvc/lib/pkgconfig or # PKG_CONFIG_PATH=/opt/cross/i386-mingw32msvc/lib/pkgconfig or
# PKG_CONFIG=arm-linux-gnueabihf-pkg-config # PKG_CONFIG=arm-linux-gnueabihf-pkg-config
PKG_CONFIG ?= pkg-config ifeq ($(CROSS_COMPILING),0)
PKG_CONFIG ?= pkg-config
else
ifneq ($(PKG_CONFIG_PATH),)
PKG_CONFIG ?= pkg-config
else
# Don't use host pkg-config when cross-compiling.
# (unknown-pkg-config is meant to be a non-existant command.)
PKG_CONFIG ?= unknown-pkg-config
endif
endif
ifneq ($(call bin_path, $(PKG_CONFIG)),) ifneq ($(call bin_path, $(PKG_CONFIG)),)
CURL_CFLAGS ?= $(shell $(PKG_CONFIG) --silence-errors --cflags libcurl) CURL_CFLAGS ?= $(shell $(PKG_CONFIG) --silence-errors --cflags libcurl)
@ -1394,6 +1404,7 @@ endif
@echo " COMPILE_PLATFORM: $(COMPILE_PLATFORM)" @echo " COMPILE_PLATFORM: $(COMPILE_PLATFORM)"
@echo " COMPILE_ARCH: $(COMPILE_ARCH)" @echo " COMPILE_ARCH: $(COMPILE_ARCH)"
@echo " HAVE_VM_COMPILED: $(HAVE_VM_COMPILED)" @echo " HAVE_VM_COMPILED: $(HAVE_VM_COMPILED)"
@echo " PKG_CONFIG: $(PKG_CONFIG)"
@echo " CC: $(CC)" @echo " CC: $(CC)"
ifeq ($(PLATFORM),mingw32) ifeq ($(PLATFORM),mingw32)
@echo " WINDRES: $(WINDRES)" @echo " WINDRES: $(WINDRES)"

View file

@ -844,6 +844,44 @@ static void CG_Portal( centity_t *cent ) {
} }
/*
================
CG_CreateRotationMatrix
================
*/
void CG_CreateRotationMatrix(vec3_t angles, vec3_t matrix[3]) {
AngleVectors(angles, matrix[0], matrix[1], matrix[2]);
VectorInverse(matrix[1]);
}
/*
================
CG_TransposeMatrix
================
*/
void CG_TransposeMatrix(vec3_t matrix[3], vec3_t transpose[3]) {
int i, j;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
transpose[i][j] = matrix[j][i];
}
}
}
/*
================
CG_RotatePoint
================
*/
void CG_RotatePoint(vec3_t point, vec3_t matrix[3]) {
vec3_t tvec;
VectorCopy(point, tvec);
point[0] = DotProduct(matrix[0], tvec);
point[1] = DotProduct(matrix[1], tvec);
point[2] = DotProduct(matrix[2], tvec);
}
/* /*
========================= =========================
CG_AdjustPositionForMover CG_AdjustPositionForMover
@ -855,6 +893,8 @@ void CG_AdjustPositionForMover(const vec3_t in, int moverNum, int fromTime, int
centity_t *cent; centity_t *cent;
vec3_t oldOrigin, origin, deltaOrigin; vec3_t oldOrigin, origin, deltaOrigin;
vec3_t oldAngles, angles, deltaAngles; vec3_t oldAngles, angles, deltaAngles;
vec3_t matrix[3], transpose[3];
vec3_t org, org2, move2;
if ( moverNum <= 0 || moverNum >= ENTITYNUM_MAX_NORMAL ) { if ( moverNum <= 0 || moverNum >= ENTITYNUM_MAX_NORMAL ) {
VectorCopy( in, out ); VectorCopy( in, out );
@ -878,9 +918,17 @@ void CG_AdjustPositionForMover(const vec3_t in, int moverNum, int fromTime, int
VectorSubtract( origin, oldOrigin, deltaOrigin ); VectorSubtract( origin, oldOrigin, deltaOrigin );
VectorSubtract( angles, oldAngles, deltaAngles ); VectorSubtract( angles, oldAngles, deltaAngles );
// origin change when on a rotating object
CG_CreateRotationMatrix( deltaAngles, transpose );
CG_TransposeMatrix( transpose, matrix );
VectorSubtract( in, oldOrigin, org );
VectorCopy( org, org2 );
CG_RotatePoint( org2, matrix );
VectorSubtract( org2, org, move2 );
VectorAdd( deltaOrigin, move2, deltaOrigin );
VectorAdd( in, deltaOrigin, out ); VectorAdd( in, deltaOrigin, out );
VectorAdd( angles_in, deltaAngles, angles_out ); VectorAdd( angles_in, deltaAngles, angles_out );
// FIXME: origin change when on a rotating object
} }

View file

@ -825,6 +825,7 @@ to be configured even if they don't have defined names.
*/ */
int Key_StringToKeynum( char *str ) { int Key_StringToKeynum( char *str ) {
keyname_t *kn; keyname_t *kn;
int n;
if ( !str || !str[0] ) { if ( !str || !str[0] ) {
return -1; return -1;
@ -834,13 +835,10 @@ int Key_StringToKeynum( char *str ) {
} }
// check for hex code // check for hex code
if ( strlen( str ) == 4 ) { n = Com_HexStrToInt( str );
int n = Com_HexStrToInt( str ); if ( n >= 0 && n < MAX_KEYS ) {
if ( n >= 0 ) {
return n; return n;
} }
}
// scan for a text match // scan for a text match
for ( kn=keynames ; kn->name ; kn++ ) { for ( kn=keynames ; kn->name ; kn++ ) {

View file

@ -98,7 +98,7 @@ void S_Base_SoundInfo(void) {
if (!s_soundStarted) { if (!s_soundStarted) {
Com_Printf ("sound system not started\n"); Com_Printf ("sound system not started\n");
} else { } else {
Com_Printf("%5d stereo\n", dma.channels - 1); Com_Printf("%5d channels\n", dma.channels);
Com_Printf("%5d samples\n", dma.samples); Com_Printf("%5d samples\n", dma.samples);
Com_Printf("%5d samplebits (%s)\n", dma.samplebits, dma.isfloat ? "float" : "int"); Com_Printf("%5d samplebits (%s)\n", dma.samplebits, dma.isfloat ? "float" : "int");
Com_Printf("%5d submission_chunk\n", dma.submission_chunk); Com_Printf("%5d submission_chunk\n", dma.submission_chunk);
@ -1242,9 +1242,6 @@ void S_GetSoundtime(void)
int samplepos; int samplepos;
static int buffers; static int buffers;
static int oldsamplepos; static int oldsamplepos;
int fullsamples;
fullsamples = dma.samples / dma.channels;
if( CL_VideoRecording( ) ) if( CL_VideoRecording( ) )
{ {
@ -1268,13 +1265,13 @@ void S_GetSoundtime(void)
if (s_paintedtime > 0x40000000) if (s_paintedtime > 0x40000000)
{ // time to chop things off to avoid 32 bit limits { // time to chop things off to avoid 32 bit limits
buffers = 0; buffers = 0;
s_paintedtime = fullsamples; s_paintedtime = dma.fullsamples;
S_Base_StopAllSounds (); S_Base_StopAllSounds ();
} }
} }
oldsamplepos = samplepos; oldsamplepos = samplepos;
s_soundtime = buffers*fullsamples + samplepos/dma.channels; s_soundtime = buffers*dma.fullsamples + samplepos/dma.channels;
#if 0 #if 0
// check to make sure that we haven't overshot // check to make sure that we haven't overshot
@ -1295,7 +1292,6 @@ void S_GetSoundtime(void)
void S_Update_(void) { void S_Update_(void) {
unsigned endtime; unsigned endtime;
int samps;
static float lastTime = 0.0f; static float lastTime = 0.0f;
float ma, op; float ma, op;
float thisTime, sane; float thisTime, sane;
@ -1339,9 +1335,8 @@ void S_Update_(void) {
& ~(dma.submission_chunk-1); & ~(dma.submission_chunk-1);
// never mix more than the complete buffer // never mix more than the complete buffer
samps = dma.samples >> (dma.channels-1); if (endtime - s_soundtime > dma.fullsamples)
if (endtime - s_soundtime > samps) endtime = s_soundtime + dma.fullsamples;
endtime = s_soundtime + samps;

View file

@ -65,6 +65,7 @@ typedef struct sfx_s {
typedef struct { typedef struct {
int channels; int channels;
int samples; // mono samples in buffer int samples; // mono samples in buffer
int fullsamples; // samples with all channels in buffer (samples divided by channels)
int submission_chunk; // don't mix less than this # int submission_chunk; // don't mix less than this #
int samplebits; int samplebits;
int isfloat; int isfloat;

View file

@ -119,24 +119,24 @@ void S_TransferStereo16 (unsigned long *pbuf, int endtime)
while (ls_paintedtime < endtime) while (ls_paintedtime < endtime)
{ {
// handle recirculating buffer issues // handle recirculating buffer issues
lpos = ls_paintedtime & ((dma.samples>>1)-1); lpos = ls_paintedtime % dma.fullsamples;
snd_out = (short *) pbuf + (lpos<<1); snd_out = (short *) pbuf + (lpos<<1); // lpos * dma.channels
snd_linear_count = (dma.samples>>1) - lpos; snd_linear_count = dma.fullsamples - lpos;
if (ls_paintedtime + snd_linear_count > endtime) if (ls_paintedtime + snd_linear_count > endtime)
snd_linear_count = endtime - ls_paintedtime; snd_linear_count = endtime - ls_paintedtime;
snd_linear_count <<= 1; snd_linear_count <<= 1; // snd_linear_count *= dma.channels
// write a linear blast of samples // write a linear blast of samples
S_WriteLinearBlastStereo16 (); S_WriteLinearBlastStereo16 ();
snd_p += snd_linear_count; snd_p += snd_linear_count;
ls_paintedtime += (snd_linear_count>>1); ls_paintedtime += (snd_linear_count>>1); // snd_linear_count / dma.channels
if( CL_VideoRecording( ) ) if( CL_VideoRecording( ) )
CL_WriteAVIAudioFrame( (byte *)snd_out, snd_linear_count << 1 ); CL_WriteAVIAudioFrame( (byte *)snd_out, snd_linear_count << 1 ); // snd_linear_count * (dma.samplebits/8)
} }
} }
@ -150,18 +150,16 @@ void S_TransferPaintBuffer(int endtime)
{ {
int out_idx; int out_idx;
int count; int count;
int out_mask;
int *p; int *p;
int step; int step;
int val; int val;
int i;
unsigned long *pbuf; unsigned long *pbuf;
pbuf = (unsigned long *)dma.buffer; pbuf = (unsigned long *)dma.buffer;
if ( s_testsound->integer ) { if ( s_testsound->integer ) {
int i;
// write a fixed sine wave // write a fixed sine wave
count = (endtime - s_paintedtime); count = (endtime - s_paintedtime);
for (i=0 ; i<count ; i++) for (i=0 ; i<count ; i++)
@ -177,53 +175,73 @@ void S_TransferPaintBuffer(int endtime)
{ // general case { // general case
p = (int *) paintbuffer; p = (int *) paintbuffer;
count = (endtime - s_paintedtime) * dma.channels; count = (endtime - s_paintedtime) * dma.channels;
out_mask = dma.samples - 1; out_idx = (s_paintedtime * dma.channels) % dma.samples;
out_idx = s_paintedtime * dma.channels & out_mask; step = 3 - MIN(dma.channels, 2);
step = 3 - dma.channels;
if ((dma.isfloat) && (dma.samplebits == 32)) if ((dma.isfloat) && (dma.samplebits == 32))
{ {
float *out = (float *) pbuf; float *out = (float *) pbuf;
while (count--) for (i=0 ; i<count ; i++)
{
if ((i % dma.channels) >= 2)
{
val = 0;
}
else
{ {
val = *p >> 8; val = *p >> 8;
p+= step; p+= step;
}
if (val > 0x7fff) if (val > 0x7fff)
val = 0x7fff; val = 0x7fff;
else if (val < -32767) /* clamp to one less than max to make division max out at -1.0f. */ else if (val < -32767) /* clamp to one less than max to make division max out at -1.0f. */
val = -32767; val = -32767;
out[out_idx] = ((float) val) / 32767.0f; out[out_idx] = ((float) val) / 32767.0f;
out_idx = (out_idx + 1) & out_mask; out_idx = (out_idx + 1) % dma.samples;
} }
} }
else if (dma.samplebits == 16) else if (dma.samplebits == 16)
{ {
short *out = (short *) pbuf; short *out = (short *) pbuf;
while (count--) for (i=0 ; i<count ; i++)
{
if ((i % dma.channels) >= 2)
{
val = 0;
}
else
{ {
val = *p >> 8; val = *p >> 8;
p+= step; p+= step;
}
if (val > 0x7fff) if (val > 0x7fff)
val = 0x7fff; val = 0x7fff;
else if (val < -32768) else if (val < -32768)
val = -32768; val = -32768;
out[out_idx] = val; out[out_idx] = val;
out_idx = (out_idx + 1) & out_mask; out_idx = (out_idx + 1) % dma.samples;
} }
} }
else if (dma.samplebits == 8) else if (dma.samplebits == 8)
{ {
unsigned char *out = (unsigned char *) pbuf; unsigned char *out = (unsigned char *) pbuf;
while (count--) for (i=0 ; i<count ; i++)
{
if ((i % dma.channels) >= 2)
{
val = 0;
}
else
{ {
val = *p >> 8; val = *p >> 8;
p+= step; p+= step;
}
if (val > 0x7fff) if (val > 0x7fff)
val = 0x7fff; val = 0x7fff;
else if (val < -32768) else if (val < -32768)
val = -32768; val = -32768;
out[out_idx] = (val>>8) + 128; out[out_idx] = (val>>8) + 128;
out_idx = (out_idx + 1) & out_mask; out_idx = (out_idx + 1) % dma.samples;
} }
} }
} }

View file

@ -5445,7 +5445,33 @@ void BotSetEntityNumForGoal(bot_goal_t *goal, char *classname) {
if ( !ent->inuse ) { if ( !ent->inuse ) {
continue; continue;
} }
if ( !Q_stricmp(ent->classname, classname) ) { if ( Q_stricmp(ent->classname, classname) != 0 ) {
continue;
}
VectorSubtract(goal->origin, ent->s.origin, dir);
if (VectorLengthSquared(dir) < Square(10)) {
goal->entitynum = i;
return;
}
}
}
/*
==================
BotSetEntityNumForGoalWithActivator
==================
*/
void BotSetEntityNumForGoalWithActivator(bot_goal_t *goal, char *classname) {
gentity_t *ent;
int i;
vec3_t dir;
ent = &g_entities[0];
for (i = 0; i < level.num_entities; i++, ent++) {
if ( !ent->inuse || !ent->activator ) {
continue;
}
if ( Q_stricmp(ent->activator->classname, classname) != 0 ) {
continue; continue;
} }
VectorSubtract(goal->origin, ent->s.origin, dir); VectorSubtract(goal->origin, ent->s.origin, dir);
@ -5526,21 +5552,21 @@ void BotSetupDeathmatchAI(void) {
else if (gametype == GT_OBELISK) { else if (gametype == GT_OBELISK) {
if (trap_BotGetLevelItemGoal(-1, "Red Obelisk", &redobelisk) < 0) if (trap_BotGetLevelItemGoal(-1, "Red Obelisk", &redobelisk) < 0)
BotAI_Print(PRT_WARNING, "Overload without Red Obelisk\n"); BotAI_Print(PRT_WARNING, "Overload without Red Obelisk\n");
BotSetEntityNumForGoal(&redobelisk, "team_redobelisk"); BotSetEntityNumForGoalWithActivator(&redobelisk, "team_redobelisk");
if (trap_BotGetLevelItemGoal(-1, "Blue Obelisk", &blueobelisk) < 0) if (trap_BotGetLevelItemGoal(-1, "Blue Obelisk", &blueobelisk) < 0)
BotAI_Print(PRT_WARNING, "Overload without Blue Obelisk\n"); BotAI_Print(PRT_WARNING, "Overload without Blue Obelisk\n");
BotSetEntityNumForGoal(&blueobelisk, "team_blueobelisk"); BotSetEntityNumForGoalWithActivator(&blueobelisk, "team_blueobelisk");
} }
else if (gametype == GT_HARVESTER) { else if (gametype == GT_HARVESTER) {
if (trap_BotGetLevelItemGoal(-1, "Red Obelisk", &redobelisk) < 0) if (trap_BotGetLevelItemGoal(-1, "Red Obelisk", &redobelisk) < 0)
BotAI_Print(PRT_WARNING, "Harvester without Red Obelisk\n"); BotAI_Print(PRT_WARNING, "Harvester without Red Obelisk\n");
BotSetEntityNumForGoal(&redobelisk, "team_redobelisk"); BotSetEntityNumForGoalWithActivator(&redobelisk, "team_redobelisk");
if (trap_BotGetLevelItemGoal(-1, "Blue Obelisk", &blueobelisk) < 0) if (trap_BotGetLevelItemGoal(-1, "Blue Obelisk", &blueobelisk) < 0)
BotAI_Print(PRT_WARNING, "Harvester without Blue Obelisk\n"); BotAI_Print(PRT_WARNING, "Harvester without Blue Obelisk\n");
BotSetEntityNumForGoal(&blueobelisk, "team_blueobelisk"); BotSetEntityNumForGoalWithActivator(&blueobelisk, "team_blueobelisk");
if (trap_BotGetLevelItemGoal(-1, "Neutral Obelisk", &neutralobelisk) < 0) if (trap_BotGetLevelItemGoal(-1, "Neutral Obelisk", &neutralobelisk) < 0)
BotAI_Print(PRT_WARNING, "Harvester without Neutral Obelisk\n"); BotAI_Print(PRT_WARNING, "Harvester without Neutral Obelisk\n");
BotSetEntityNumForGoal(&neutralobelisk, "team_neutralobelisk"); BotSetEntityNumForGoalWithActivator(&neutralobelisk, "team_neutralobelisk");
} }
#endif #endif

View file

@ -104,6 +104,7 @@ MULTIPLAYER MENU (SERVER BROWSER)
#define UIAS_GLOBAL4 5 #define UIAS_GLOBAL4 5
#define UIAS_GLOBAL5 6 #define UIAS_GLOBAL5 6
#define UIAS_FAVORITES 7 #define UIAS_FAVORITES 7
#define UIAS_NUM_SOURCES 8
#define UI_MAX_MASTER_SERVERS 6 #define UI_MAX_MASTER_SERVERS 6
@ -112,6 +113,7 @@ MULTIPLAYER MENU (SERVER BROWSER)
#define SORT_CLIENTS 2 #define SORT_CLIENTS 2
#define SORT_GAME 3 #define SORT_GAME 3
#define SORT_PING 4 #define SORT_PING 4
#define SORT_NUM_SORTS 5
#define GAMES_ALL 0 #define GAMES_ALL 0
// STONELANCE // STONELANCE
@ -129,6 +131,7 @@ MULTIPLAYER MENU (SERVER BROWSER)
#define GAMES_TEAM_RACING_DM 6 #define GAMES_TEAM_RACING_DM 6
#define GAMES_TEAMPLAY 7 #define GAMES_TEAMPLAY 7
#define GAMES_CTF 8 #define GAMES_CTF 8
#define GAMES_NUM_GAMES 9
// END // END
static const char *master_items[] = { static const char *master_items[] = {
@ -1303,7 +1306,7 @@ int ArenaServers_SetType( int type )
char masterstr[2], cvarname[sizeof("sv_master1")]; char masterstr[2], cvarname[sizeof("sv_master1")];
int direction; int direction;
if (type == g_servertype || type == ((g_servertype+1) % (ARRAY_LEN(master_items)-1))) { if (type == g_servertype || type == ((g_servertype+1) % UIAS_NUM_SOURCES)) {
direction = 1; direction = 1;
} else { } else {
direction = -1; direction = -1;
@ -1906,16 +1909,12 @@ static void ArenaServers_MenuInit( void ) {
ArenaServers_LoadFavorites(); ArenaServers_LoadFavorites();
g_arenaservers.master.curvalue = g_servertype = Com_Clamp( 0, 6, ui_browserMaster.integer ); g_arenaservers.master.curvalue = g_servertype = Com_Clamp( 0, UIAS_NUM_SOURCES-1, ui_browserMaster.integer );
// STONELANCE g_gametype = Com_Clamp( 0, GAMES_NUM_GAMES-1, ui_browserGameType.integer );
// g_gametype = Com_Clamp( 0, 4, ui_browserGameType.integer );
g_gametype = Com_Clamp( 0, GT_MAX_GAME_TYPE, ui_browserGameType.integer );
// END
g_arenaservers.gametype.curvalue = g_gametype; g_arenaservers.gametype.curvalue = g_gametype;
g_sortkey = Com_Clamp( 0, SORT_NUM_SORTS-1, ui_browserSortKey.integer );
g_sortkey = Com_Clamp( 0, 4, ui_browserSortKey.integer );
g_arenaservers.sortkey.curvalue = g_sortkey; g_arenaservers.sortkey.curvalue = g_sortkey;
g_fullservers = Com_Clamp( 0, 1, ui_browserShowFull.integer ); g_fullservers = Com_Clamp( 0, 1, ui_browserShowFull.integer );

View file

@ -58,11 +58,6 @@ static void Matrix34Multiply( float *a, float *b, float *out ) {
out[10] = a[8] * b[2] + a[9] * b[6] + a[10] * b[10]; out[10] = a[8] * b[2] + a[9] * b[6] + a[10] * b[10];
out[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11]; out[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11];
} }
static void Matrix34Multiply_OnlySetOrigin( float *a, float *b, float *out ) {
out[ 3] = a[0] * b[3] + a[1] * b[7] + a[ 2] * b[11] + a[ 3];
out[ 7] = a[4] * b[3] + a[5] * b[7] + a[ 6] * b[11] + a[ 7];
out[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11];
}
static void InterpolateMatrix( float *a, float *b, float lerp, float *mat ) { static void InterpolateMatrix( float *a, float *b, float lerp, float *mat ) {
float unLerp = 1.0f - lerp; float unLerp = 1.0f - lerp;
@ -571,6 +566,8 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
} }
if( header->ofs_bounds ) { if( header->ofs_bounds ) {
size += header->num_frames * 6 * sizeof(float); // model bounds size += header->num_frames * 6 * sizeof(float); // model bounds
} else if( header->num_meshes && header->num_frames == 0 ) {
size += 6 * sizeof(float); // model bounds
} }
mod->type = MOD_IQM; mod->type = MOD_IQM;
@ -646,6 +643,9 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
if( header->ofs_bounds ) { if( header->ofs_bounds ) {
iqmData->bounds = (float*)dataPtr; iqmData->bounds = (float*)dataPtr;
dataPtr += header->num_frames * 6 * sizeof(float); // model bounds dataPtr += header->num_frames * 6 * sizeof(float); // model bounds
} else if( header->num_meshes && header->num_frames == 0 ) {
iqmData->bounds = (float*)dataPtr;
dataPtr += 6 * sizeof(float); // model bounds
} }
if( header->num_meshes ) if( header->num_meshes )
@ -912,6 +912,15 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
bounds++; bounds++;
} }
} }
else if( header->num_meshes && header->num_frames == 0 )
{
mat = iqmData->bounds;
ClearBounds( &iqmData->bounds[0], &iqmData->bounds[3] );
for ( i = 0 ; i < header->num_vertexes ; i++ ) {
AddPointToBounds( &iqmData->positions[i*3], &iqmData->bounds[0], &iqmData->bounds[3] );
}
}
return qtrue; return qtrue;
} }
@ -1124,18 +1133,6 @@ static void ComputePoseMats( iqmData_t *data, int frame, int oldframe,
int *joint = data->jointParents; int *joint = data->jointParents;
int i; int i;
if ( data->num_poses == 0 ) {
for( i = 0; i < data->num_joints; i++, joint++ ) {
if( *joint >= 0 ) {
Matrix34Multiply( mat + 12 * *joint,
identityMatrix, mat + 12*i );
} else {
Com_Memcpy( mat + 12*i, identityMatrix, 12 * sizeof(float) );
}
}
return;
}
if ( oldframe == frame ) { if ( oldframe == frame ) {
mat1 = data->poseMats + 12 * data->num_poses * frame; mat1 = data->poseMats + 12 * data->num_poses * frame;
for( i = 0; i < data->num_poses; i++, joint++ ) { for( i = 0; i < data->num_poses; i++, joint++ ) {
@ -1171,6 +1168,11 @@ static void ComputeJointMats( iqmData_t *data, int frame, int oldframe,
float *mat1; float *mat1;
int i; int i;
if ( data->num_poses == 0 ) {
Com_Memcpy( mat, data->jointMats, data->num_joints * 12 * sizeof(float) );
return;
}
ComputePoseMats( data, frame, oldframe, backlerp, mat ); ComputePoseMats( data, frame, oldframe, backlerp, mat );
for( i = 0; i < data->num_joints; i++ ) { for( i = 0; i < data->num_joints; i++ ) {
@ -1179,7 +1181,7 @@ static void ComputeJointMats( iqmData_t *data, int frame, int oldframe,
Com_Memcpy(outmat, mat1, sizeof(outmat)); Com_Memcpy(outmat, mat1, sizeof(outmat));
Matrix34Multiply_OnlySetOrigin( outmat, data->jointMats + 12 * i, mat1 ); Matrix34Multiply( outmat, data->jointMats + 12*i, mat1 );
} }
} }
@ -1194,7 +1196,7 @@ Compute vertices for this model surface
void RB_IQMSurfaceAnim( surfaceType_t *surface ) { void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
srfIQModel_t *surf = (srfIQModel_t *)surface; srfIQModel_t *surf = (srfIQModel_t *)surface;
iqmData_t *data = surf->data; iqmData_t *data = surf->data;
float jointMats[IQM_MAX_JOINTS * 12]; float poseMats[IQM_MAX_JOINTS * 12];
float influenceVtxMat[SHADER_MAX_VERTEXES * 12]; float influenceVtxMat[SHADER_MAX_VERTEXES * 12];
float influenceNrmMat[SHADER_MAX_VERTEXES * 9]; float influenceNrmMat[SHADER_MAX_VERTEXES * 9];
int i; int i;
@ -1235,7 +1237,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
if ( data->num_poses > 0 ) { if ( data->num_poses > 0 ) {
// compute interpolated joint matrices // compute interpolated joint matrices
ComputePoseMats( data, frame, oldframe, backlerp, jointMats ); ComputePoseMats( data, frame, oldframe, backlerp, poseMats );
// compute vertex blend influence matricies // compute vertex blend influence matricies
for( i = 0; i < surf->num_influences; i++ ) { for( i = 0; i < surf->num_influences; i++ ) {
@ -1273,32 +1275,32 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
} else { } else {
// compute the vertex matrix by blending the up to // compute the vertex matrix by blending the up to
// four blend weights // four blend weights
vtxMat[0] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 0]; vtxMat[0] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 0];
vtxMat[1] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 1]; vtxMat[1] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 1];
vtxMat[2] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 2]; vtxMat[2] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 2];
vtxMat[3] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 3]; vtxMat[3] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 3];
vtxMat[4] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 4]; vtxMat[4] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 4];
vtxMat[5] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 5]; vtxMat[5] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 5];
vtxMat[6] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 6]; vtxMat[6] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 6];
vtxMat[7] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 7]; vtxMat[7] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 7];
vtxMat[8] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 8]; vtxMat[8] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 8];
vtxMat[9] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 9]; vtxMat[9] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 9];
vtxMat[10] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 10]; vtxMat[10] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 10];
vtxMat[11] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 11]; vtxMat[11] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 11];
for( j = 1; j < numWeights; j++ ) { for( j = 1; j < numWeights; j++ ) {
vtxMat[0] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 0]; vtxMat[0] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 0];
vtxMat[1] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 1]; vtxMat[1] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 1];
vtxMat[2] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 2]; vtxMat[2] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 2];
vtxMat[3] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 3]; vtxMat[3] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 3];
vtxMat[4] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 4]; vtxMat[4] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 4];
vtxMat[5] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 5]; vtxMat[5] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 5];
vtxMat[6] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 6]; vtxMat[6] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 6];
vtxMat[7] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 7]; vtxMat[7] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 7];
vtxMat[8] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 8]; vtxMat[8] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 8];
vtxMat[9] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 9]; vtxMat[9] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 9];
vtxMat[10] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 10]; vtxMat[10] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 10];
vtxMat[11] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 11]; vtxMat[11] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 11];
} }
} }

View file

@ -58,11 +58,6 @@ static void Matrix34Multiply( float *a, float *b, float *out ) {
out[10] = a[8] * b[2] + a[9] * b[6] + a[10] * b[10]; out[10] = a[8] * b[2] + a[9] * b[6] + a[10] * b[10];
out[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11]; out[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11];
} }
static void Matrix34Multiply_OnlySetOrigin( float *a, float *b, float *out ) {
out[ 3] = a[0] * b[3] + a[1] * b[7] + a[ 2] * b[11] + a[ 3];
out[ 7] = a[4] * b[3] + a[5] * b[7] + a[ 6] * b[11] + a[ 7];
out[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11];
}
static void InterpolateMatrix( float *a, float *b, float lerp, float *mat ) { static void InterpolateMatrix( float *a, float *b, float lerp, float *mat ) {
float unLerp = 1.0f - lerp; float unLerp = 1.0f - lerp;
@ -574,6 +569,8 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
} }
if( header->ofs_bounds ) { if( header->ofs_bounds ) {
size += header->num_frames * 6 * sizeof(float); // model bounds size += header->num_frames * 6 * sizeof(float); // model bounds
} else if( header->num_meshes && header->num_frames == 0 ) {
size += 6 * sizeof(float); // model bounds
} }
mod->type = MOD_IQM; mod->type = MOD_IQM;
@ -649,6 +646,9 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
if( header->ofs_bounds ) { if( header->ofs_bounds ) {
iqmData->bounds = (float*)dataPtr; iqmData->bounds = (float*)dataPtr;
dataPtr += header->num_frames * 6 * sizeof(float); // model bounds dataPtr += header->num_frames * 6 * sizeof(float); // model bounds
} else if( header->num_meshes && header->num_frames == 0 ) {
iqmData->bounds = (float*)dataPtr;
dataPtr += 6 * sizeof(float); // model bounds
} }
if( header->num_meshes ) if( header->num_meshes )
@ -915,6 +915,15 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
bounds++; bounds++;
} }
} }
else if( header->num_meshes && header->num_frames == 0 )
{
mat = iqmData->bounds;
ClearBounds( &iqmData->bounds[0], &iqmData->bounds[3] );
for ( i = 0 ; i < header->num_vertexes ; i++ ) {
AddPointToBounds( &iqmData->positions[i*3], &iqmData->bounds[0], &iqmData->bounds[3] );
}
}
// Create VAO surfaces // Create VAO surfaces
if ( iqmData->num_surfaces && iqmData->num_joints <= glRefConfig.glslMaxAnimatedBones ) if ( iqmData->num_surfaces && iqmData->num_joints <= glRefConfig.glslMaxAnimatedBones )
@ -1302,18 +1311,6 @@ static void ComputePoseMats( iqmData_t *data, int frame, int oldframe,
int *joint = data->jointParents; int *joint = data->jointParents;
int i; int i;
if ( data->num_poses == 0 ) {
for( i = 0; i < data->num_joints; i++, joint++ ) {
if( *joint >= 0 ) {
Matrix34Multiply( mat + 12 * *joint,
identityMatrix, mat + 12*i );
} else {
Com_Memcpy( mat + 12*i, identityMatrix, 12 * sizeof(float) );
}
}
return;
}
if ( oldframe == frame ) { if ( oldframe == frame ) {
mat1 = data->poseMats + 12 * data->num_poses * frame; mat1 = data->poseMats + 12 * data->num_poses * frame;
for( i = 0; i < data->num_poses; i++, joint++ ) { for( i = 0; i < data->num_poses; i++, joint++ ) {
@ -1349,6 +1346,11 @@ static void ComputeJointMats( iqmData_t *data, int frame, int oldframe,
float *mat1; float *mat1;
int i; int i;
if ( data->num_poses == 0 ) {
Com_Memcpy( mat, data->jointMats, data->num_joints * 12 * sizeof(float) );
return;
}
ComputePoseMats( data, frame, oldframe, backlerp, mat ); ComputePoseMats( data, frame, oldframe, backlerp, mat );
for( i = 0; i < data->num_joints; i++ ) { for( i = 0; i < data->num_joints; i++ ) {
@ -1357,7 +1359,7 @@ static void ComputeJointMats( iqmData_t *data, int frame, int oldframe,
Com_Memcpy(outmat, mat1, sizeof(outmat)); Com_Memcpy(outmat, mat1, sizeof(outmat));
Matrix34Multiply_OnlySetOrigin( outmat, data->jointMats + 12 * i, mat1 ); Matrix34Multiply( outmat, data->jointMats + 12*i, mat1 );
} }
} }
@ -1372,7 +1374,7 @@ Compute vertices for this model surface
void RB_IQMSurfaceAnim( surfaceType_t *surface ) { void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
srfIQModel_t *surf = (srfIQModel_t *)surface; srfIQModel_t *surf = (srfIQModel_t *)surface;
iqmData_t *data = surf->data; iqmData_t *data = surf->data;
float jointMats[IQM_MAX_JOINTS * 12]; float poseMats[IQM_MAX_JOINTS * 12];
float influenceVtxMat[SHADER_MAX_VERTEXES * 12]; float influenceVtxMat[SHADER_MAX_VERTEXES * 12];
float influenceNrmMat[SHADER_MAX_VERTEXES * 9]; float influenceNrmMat[SHADER_MAX_VERTEXES * 9];
int i; int i;
@ -1417,7 +1419,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
if ( data->num_poses > 0 ) { if ( data->num_poses > 0 ) {
// compute interpolated joint matrices // compute interpolated joint matrices
ComputePoseMats( data, frame, oldframe, backlerp, jointMats ); ComputePoseMats( data, frame, oldframe, backlerp, poseMats );
// compute vertex blend influence matricies // compute vertex blend influence matricies
for( i = 0; i < surf->num_influences; i++ ) { for( i = 0; i < surf->num_influences; i++ ) {
@ -1455,32 +1457,32 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
} else { } else {
// compute the vertex matrix by blending the up to // compute the vertex matrix by blending the up to
// four blend weights // four blend weights
vtxMat[0] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 0]; vtxMat[0] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 0];
vtxMat[1] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 1]; vtxMat[1] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 1];
vtxMat[2] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 2]; vtxMat[2] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 2];
vtxMat[3] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 3]; vtxMat[3] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 3];
vtxMat[4] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 4]; vtxMat[4] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 4];
vtxMat[5] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 5]; vtxMat[5] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 5];
vtxMat[6] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 6]; vtxMat[6] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 6];
vtxMat[7] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 7]; vtxMat[7] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 7];
vtxMat[8] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 8]; vtxMat[8] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 8];
vtxMat[9] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 9]; vtxMat[9] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 9];
vtxMat[10] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 10]; vtxMat[10] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 10];
vtxMat[11] = blendWeights[0] * jointMats[12 * data->influenceBlendIndexes[4*influence + 0] + 11]; vtxMat[11] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 11];
for( j = 1; j < numWeights; j++ ) { for( j = 1; j < numWeights; j++ ) {
vtxMat[0] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 0]; vtxMat[0] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 0];
vtxMat[1] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 1]; vtxMat[1] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 1];
vtxMat[2] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 2]; vtxMat[2] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 2];
vtxMat[3] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 3]; vtxMat[3] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 3];
vtxMat[4] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 4]; vtxMat[4] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 4];
vtxMat[5] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 5]; vtxMat[5] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 5];
vtxMat[6] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 6]; vtxMat[6] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 6];
vtxMat[7] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 7]; vtxMat[7] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 7];
vtxMat[8] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 8]; vtxMat[8] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 8];
vtxMat[9] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 9]; vtxMat[9] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 9];
vtxMat[10] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 10]; vtxMat[10] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 10];
vtxMat[11] += blendWeights[j] * jointMats[12 * data->influenceBlendIndexes[4*influence + j] + 11]; vtxMat[11] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 11];
} }
} }

View file

@ -188,9 +188,6 @@ qboolean SNDDMA_Init(void)
SDL_AudioSpec desired; SDL_AudioSpec desired;
SDL_AudioSpec obtained; SDL_AudioSpec obtained;
int tmp; int tmp;
#ifdef USE_SDL_AUDIO_CAPTURE
SDL_version sdlVersion;
#endif
if (snd_inited) if (snd_inited)
return qtrue; return qtrue;
@ -267,20 +264,15 @@ qboolean SNDDMA_Init(void)
if (!tmp) if (!tmp)
tmp = (obtained.samples * obtained.channels) * 10; tmp = (obtained.samples * obtained.channels) * 10;
if (tmp & (tmp - 1)) // not a power of two? Seems to confuse something. // samples must be divisible by number of channels
{ tmp -= tmp % obtained.channels;
int val = 1;
while (val < tmp)
val <<= 1;
tmp = val;
}
dmapos = 0; dmapos = 0;
dma.samplebits = SDL_AUDIO_BITSIZE(obtained.format); dma.samplebits = SDL_AUDIO_BITSIZE(obtained.format);
dma.isfloat = SDL_AUDIO_ISFLOAT(obtained.format); dma.isfloat = SDL_AUDIO_ISFLOAT(obtained.format);
dma.channels = obtained.channels; dma.channels = obtained.channels;
dma.samples = tmp; dma.samples = tmp;
dma.fullsamples = dma.samples / dma.channels;
dma.submission_chunk = 1; dma.submission_chunk = 1;
dma.speed = obtained.freq; dma.speed = obtained.freq;
dmasize = (dma.samples * (dma.samplebits/8)); dmasize = (dma.samples * (dma.samplebits/8));
@ -289,11 +281,10 @@ qboolean SNDDMA_Init(void)
#ifdef USE_SDL_AUDIO_CAPTURE #ifdef USE_SDL_AUDIO_CAPTURE
// !!! FIXME: some of these SDL_OpenAudioDevice() values should be cvars. // !!! FIXME: some of these SDL_OpenAudioDevice() values should be cvars.
s_sdlCapture = Cvar_Get( "s_sdlCapture", "1", CVAR_ARCHIVE | CVAR_LATCH ); s_sdlCapture = Cvar_Get( "s_sdlCapture", "1", CVAR_ARCHIVE | CVAR_LATCH );
// !!! FIXME: hopefully pulseaudio capture will be fixed in SDL 2.0.9... https://bugzilla.libsdl.org/show_bug.cgi?id=4087 // !!! FIXME: pulseaudio capture records audio the entire time the program is running. https://bugzilla.libsdl.org/show_bug.cgi?id=4087
SDL_GetVersion(&sdlVersion); if (Q_stricmp(SDL_GetCurrentAudioDriver(), "pulseaudio") == 0)
if (sdlVersion.major == 2 && sdlVersion.minor == 0 && sdlVersion.patch < 9 && Q_stricmp(SDL_GetCurrentAudioDriver(), "pulseaudio") == 0)
{ {
Com_Printf("SDL audio capture support disabled (pulseaudio capture does not work correctly with SDL %d.%d.%d)\n", sdlVersion.major, sdlVersion.minor, sdlVersion.patch); Com_Printf("SDL audio capture support disabled for pulseaudio (https://bugzilla.libsdl.org/show_bug.cgi?id=4087)\n");
} }
else if (!s_sdlCapture->integer) else if (!s_sdlCapture->integer)
{ {